Merge pull request #444 from dbabokin/master

Fixing tabs and trainling white spaces
This commit is contained in:
Dmitry Babokin
2013-03-18 05:39:13 -07:00
34 changed files with 1766 additions and 1766 deletions

26
ast.cpp
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file ast.cpp /** @file ast.cpp
@@ -109,20 +109,20 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
es->expr = (Expr *)WalkAST(es->expr, preFunc, postFunc, data); es->expr = (Expr *)WalkAST(es->expr, preFunc, postFunc, data);
else if ((ds = dynamic_cast<DeclStmt *>(node)) != NULL) { else if ((ds = dynamic_cast<DeclStmt *>(node)) != NULL) {
for (unsigned int i = 0; i < ds->vars.size(); ++i) for (unsigned int i = 0; i < ds->vars.size(); ++i)
ds->vars[i].init = (Expr *)WalkAST(ds->vars[i].init, preFunc, ds->vars[i].init = (Expr *)WalkAST(ds->vars[i].init, preFunc,
postFunc, data); postFunc, data);
} }
else if ((is = dynamic_cast<IfStmt *>(node)) != NULL) { else if ((is = dynamic_cast<IfStmt *>(node)) != NULL) {
is->test = (Expr *)WalkAST(is->test, preFunc, postFunc, data); is->test = (Expr *)WalkAST(is->test, preFunc, postFunc, data);
is->trueStmts = (Stmt *)WalkAST(is->trueStmts, preFunc, is->trueStmts = (Stmt *)WalkAST(is->trueStmts, preFunc,
postFunc, data); postFunc, data);
is->falseStmts = (Stmt *)WalkAST(is->falseStmts, preFunc, is->falseStmts = (Stmt *)WalkAST(is->falseStmts, preFunc,
postFunc, data); postFunc, data);
} }
else if ((dos = dynamic_cast<DoStmt *>(node)) != NULL) { else if ((dos = dynamic_cast<DoStmt *>(node)) != NULL) {
dos->testExpr = (Expr *)WalkAST(dos->testExpr, preFunc, dos->testExpr = (Expr *)WalkAST(dos->testExpr, preFunc,
postFunc, data); postFunc, data);
dos->bodyStmts = (Stmt *)WalkAST(dos->bodyStmts, preFunc, dos->bodyStmts = (Stmt *)WalkAST(dos->bodyStmts, preFunc,
postFunc, data); postFunc, data);
} }
else if ((fs = dynamic_cast<ForStmt *>(node)) != NULL) { else if ((fs = dynamic_cast<ForStmt *>(node)) != NULL) {
@@ -133,10 +133,10 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
} }
else if ((fes = dynamic_cast<ForeachStmt *>(node)) != NULL) { else if ((fes = dynamic_cast<ForeachStmt *>(node)) != NULL) {
for (unsigned int i = 0; i < fes->startExprs.size(); ++i) for (unsigned int i = 0; i < fes->startExprs.size(); ++i)
fes->startExprs[i] = (Expr *)WalkAST(fes->startExprs[i], preFunc, fes->startExprs[i] = (Expr *)WalkAST(fes->startExprs[i], preFunc,
postFunc, data); postFunc, data);
for (unsigned int i = 0; i < fes->endExprs.size(); ++i) for (unsigned int i = 0; i < fes->endExprs.size(); ++i)
fes->endExprs[i] = (Expr *)WalkAST(fes->endExprs[i], preFunc, fes->endExprs[i] = (Expr *)WalkAST(fes->endExprs[i], preFunc,
postFunc, data); postFunc, data);
fes->stmts = (Stmt *)WalkAST(fes->stmts, preFunc, postFunc, data); fes->stmts = (Stmt *)WalkAST(fes->stmts, preFunc, postFunc, data);
} }
@@ -217,7 +217,7 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
} }
else if ((el = dynamic_cast<ExprList *>(node)) != NULL) { else if ((el = dynamic_cast<ExprList *>(node)) != NULL) {
for (unsigned int i = 0; i < el->exprs.size(); ++i) for (unsigned int i = 0; i < el->exprs.size(); ++i)
el->exprs[i] = (Expr *)WalkAST(el->exprs[i], preFunc, el->exprs[i] = (Expr *)WalkAST(el->exprs[i], preFunc,
postFunc, data); postFunc, data);
} }
else if ((fce = dynamic_cast<FunctionCallExpr *>(node)) != NULL) { else if ((fce = dynamic_cast<FunctionCallExpr *>(node)) != NULL) {
@@ -247,9 +247,9 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
else if ((aoe = dynamic_cast<AddressOfExpr *>(node)) != NULL) else if ((aoe = dynamic_cast<AddressOfExpr *>(node)) != NULL)
aoe->expr = (Expr *)WalkAST(aoe->expr, preFunc, postFunc, data); aoe->expr = (Expr *)WalkAST(aoe->expr, preFunc, postFunc, data);
else if ((newe = dynamic_cast<NewExpr *>(node)) != NULL) { else if ((newe = dynamic_cast<NewExpr *>(node)) != NULL) {
newe->countExpr = (Expr *)WalkAST(newe->countExpr, preFunc, newe->countExpr = (Expr *)WalkAST(newe->countExpr, preFunc,
postFunc, data); postFunc, data);
newe->initExpr = (Expr *)WalkAST(newe->initExpr, preFunc, newe->initExpr = (Expr *)WalkAST(newe->initExpr, preFunc,
postFunc, data); postFunc, data);
} }
else if (dynamic_cast<SymbolExpr *>(node) != NULL || else if (dynamic_cast<SymbolExpr *>(node) != NULL ||
@@ -257,9 +257,9 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
dynamic_cast<FunctionSymbolExpr *>(node) != NULL || dynamic_cast<FunctionSymbolExpr *>(node) != NULL ||
dynamic_cast<SyncExpr *>(node) != NULL || dynamic_cast<SyncExpr *>(node) != NULL ||
dynamic_cast<NullPointerExpr *>(node) != NULL) { dynamic_cast<NullPointerExpr *>(node) != NULL) {
// nothing to do // nothing to do
} }
else else
FATAL("Unhandled expression type in WalkAST()."); FATAL("Unhandled expression type in WalkAST().");
} }

10
ast.h
View File

@@ -28,11 +28,11 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file ast.h /** @file ast.h
@brief @brief
*/ */
#ifndef ISPC_AST_H #ifndef ISPC_AST_H
@@ -121,12 +121,12 @@ extern ASTNode *Optimize(ASTNode *root);
/** Convenience version of Optimize() for Expr *s that returns an Expr * /** Convenience version of Optimize() for Expr *s that returns an Expr *
(rather than an ASTNode *, which would require the caller to cast back (rather than an ASTNode *, which would require the caller to cast back
to an Expr *). */ to an Expr *). */
extern Expr *Optimize(Expr *); extern Expr *Optimize(Expr *);
/** Convenience version of Optimize() for Expr *s that returns an Stmt * /** Convenience version of Optimize() for Expr *s that returns an Stmt *
(rather than an ASTNode *, which would require the caller to cast back (rather than an ASTNode *, which would require the caller to cast back
to a Stmt *). */ to a Stmt *). */
extern Stmt *Optimize(Stmt *); extern Stmt *Optimize(Stmt *);
/** Perform type-checking on the given AST (or portion of one), returning a /** Perform type-checking on the given AST (or portion of one), returning a
@@ -144,7 +144,7 @@ extern Stmt *TypeCheck(Stmt *);
extern int EstimateCost(ASTNode *root); extern int EstimateCost(ASTNode *root);
/** Returns true if it would be safe to run the given code with an "all /** Returns true if it would be safe to run the given code with an "all
off" mask. */ off" mask. */
extern bool SafeToRunWithMaskAllOff(ASTNode *root); extern bool SafeToRunWithMaskAllOff(ASTNode *root);
#endif // ISPC_AST_H #endif // ISPC_AST_H

View File

@@ -28,11 +28,11 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file builtins.cpp /** @file builtins.cpp
@brief Definitions of functions related to setting up the standard library @brief Definitions of functions related to setting up the standard library
and other builtins. and other builtins.
*/ */
@@ -169,9 +169,9 @@ lLLVMTypeToISPCType(const llvm::Type *t, bool intAsUnsigned) {
static void static void
lCreateSymbol(const std::string &name, const Type *returnType, lCreateSymbol(const std::string &name, const Type *returnType,
llvm::SmallVector<const Type *, 8> &argTypes, llvm::SmallVector<const Type *, 8> &argTypes,
const llvm::FunctionType *ftype, llvm::Function *func, const llvm::FunctionType *ftype, llvm::Function *func,
SymbolTable *symbolTable) { SymbolTable *symbolTable) {
SourcePos noPos; SourcePos noPos;
noPos.name = "__stdlib"; noPos.name = "__stdlib";
@@ -251,7 +251,7 @@ lCreateISPCSymbol(llvm::Function *func, SymbolTable *symbolTable) {
"representable for builtin %s", j, name.c_str()); "representable for builtin %s", j, name.c_str());
return false; return false;
} }
anyIntArgs |= anyIntArgs |=
(Type::Equal(type, lLLVMTypeToISPCType(llvmArgType, !intAsUnsigned)) == false); (Type::Equal(type, lLLVMTypeToISPCType(llvmArgType, !intAsUnsigned)) == false);
argTypes.push_back(type); argTypes.push_back(type);
} }
@@ -286,7 +286,7 @@ lAddModuleSymbols(llvm::Module *module, SymbolTable *symbolTable) {
/** In many of the builtins-*.ll files, we have declarations of various LLVM /** In many of the builtins-*.ll files, we have declarations of various LLVM
intrinsics that are then used in the implementation of various target- intrinsics that are then used in the implementation of various target-
specific functions. This function loops over all of the intrinsic specific functions. This function loops over all of the intrinsic
declarations and makes sure that the signature we have in our .ll file declarations and makes sure that the signature we have in our .ll file
matches the signature of the actual intrinsic. matches the signature of the actual intrinsic.
*/ */
@@ -304,7 +304,7 @@ lCheckModuleIntrinsics(llvm::Module *module) {
if (!strncmp(funcName.c_str(), "llvm.x86.", 9)) { if (!strncmp(funcName.c_str(), "llvm.x86.", 9)) {
llvm::Intrinsic::ID id = (llvm::Intrinsic::ID)func->getIntrinsicID(); llvm::Intrinsic::ID id = (llvm::Intrinsic::ID)func->getIntrinsicID();
Assert(id != 0); Assert(id != 0);
llvm::Type *intrinsicType = llvm::Type *intrinsicType =
llvm::Intrinsic::getType(*g->ctx, id); llvm::Intrinsic::getType(*g->ctx, id);
intrinsicType = llvm::PointerType::get(intrinsicType, 0); intrinsicType = llvm::PointerType::get(intrinsicType, 0);
Assert(func->getType() == intrinsicType); Assert(func->getType() == intrinsicType);
@@ -410,7 +410,7 @@ lSetInternalFunctions(llvm::Module *module) {
"__delete_varying", "__delete_varying",
"__do_assert_uniform", "__do_assert_uniform",
"__do_assert_varying", "__do_assert_varying",
"__do_print", "__do_print",
"__doublebits_uniform_int64", "__doublebits_uniform_int64",
"__doublebits_varying_int64", "__doublebits_varying_int64",
"__exclusive_scan_add_double", "__exclusive_scan_add_double",
@@ -654,7 +654,7 @@ AddBitcodeToModule(const unsigned char *bitcode, int length,
bcModule->setDataLayout(module->getDataLayout()); bcModule->setDataLayout(module->getDataLayout());
std::string(linkError); std::string(linkError);
if (llvm::Linker::LinkModules(module, bcModule, if (llvm::Linker::LinkModules(module, bcModule,
llvm::Linker::DestroySource, llvm::Linker::DestroySource,
&linkError)) &linkError))
Error(SourcePos(), "Error linking stdlib bitcode: %s", linkError.c_str()); Error(SourcePos(), "Error linking stdlib bitcode: %s", linkError.c_str());
@@ -672,7 +672,7 @@ AddBitcodeToModule(const unsigned char *bitcode, int length,
static void static void
lDefineConstantInt(const char *name, int val, llvm::Module *module, lDefineConstantInt(const char *name, int val, llvm::Module *module,
SymbolTable *symbolTable) { SymbolTable *symbolTable) {
Symbol *sym = Symbol *sym =
new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(), new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(),
SC_STATIC); SC_STATIC);
sym->constValue = new ConstExpr(sym->type, val, SourcePos()); sym->constValue = new ConstExpr(sym->type, val, SourcePos());
@@ -694,8 +694,8 @@ lDefineConstantInt(const char *name, int val, llvm::Module *module,
// FIXME? DWARF says that this (and programIndex below) should // FIXME? DWARF says that this (and programIndex below) should
// have the DW_AT_artifical attribute. It's not clear if this // have the DW_AT_artifical attribute. It's not clear if this
// matters for anything though. // matters for anything though.
llvm::DIGlobalVariable var = llvm::DIGlobalVariable var =
m->diBuilder->createGlobalVariable(name, m->diBuilder->createGlobalVariable(name,
file, file,
0 /* line */, 0 /* line */,
diType, diType,
@@ -732,8 +732,8 @@ lDefineConstantIntFunc(const char *name, int val, llvm::Module *module,
static void static void
lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) { lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) {
Symbol *sym = Symbol *sym =
new Symbol("programIndex", SourcePos(), new Symbol("programIndex", SourcePos(),
AtomicType::VaryingInt32->GetAsConstType(), SC_STATIC); AtomicType::VaryingInt32->GetAsConstType(), SC_STATIC);
int pi[ISPC_MAX_NVEC]; int pi[ISPC_MAX_NVEC];
@@ -755,7 +755,7 @@ lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) {
llvm::DIType diType = sym->type->GetDIType(file); llvm::DIType diType = sym->type->GetDIType(file);
Assert(diType.Verify()); Assert(diType.Verify());
llvm::DIGlobalVariable var = llvm::DIGlobalVariable var =
m->diBuilder->createGlobalVariable(sym->name.c_str(), m->diBuilder->createGlobalVariable(sym->name.c_str(),
file, file,
0 /* line */, 0 /* line */,
diType, diType,
@@ -773,13 +773,13 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
if (g->target.is32Bit) { if (g->target.is32Bit) {
extern unsigned char builtins_bitcode_c_32[]; extern unsigned char builtins_bitcode_c_32[];
extern int builtins_bitcode_c_32_length; extern int builtins_bitcode_c_32_length;
AddBitcodeToModule(builtins_bitcode_c_32, builtins_bitcode_c_32_length, AddBitcodeToModule(builtins_bitcode_c_32, builtins_bitcode_c_32_length,
module, symbolTable); module, symbolTable);
} }
else { else {
extern unsigned char builtins_bitcode_c_64[]; extern unsigned char builtins_bitcode_c_64[];
extern int builtins_bitcode_c_64_length; extern int builtins_bitcode_c_64_length;
AddBitcodeToModule(builtins_bitcode_c_64, builtins_bitcode_c_64_length, AddBitcodeToModule(builtins_bitcode_c_64, builtins_bitcode_c_64_length,
module, symbolTable); module, symbolTable);
} }
@@ -792,12 +792,12 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
extern unsigned char builtins_bitcode_sse2_x2[]; extern unsigned char builtins_bitcode_sse2_x2[];
extern int builtins_bitcode_sse2_x2_length; extern int builtins_bitcode_sse2_x2_length;
switch (g->target.vectorWidth) { switch (g->target.vectorWidth) {
case 4: case 4:
AddBitcodeToModule(builtins_bitcode_sse2, builtins_bitcode_sse2_length, AddBitcodeToModule(builtins_bitcode_sse2, builtins_bitcode_sse2_length,
module, symbolTable); module, symbolTable);
break; break;
case 8: case 8:
AddBitcodeToModule(builtins_bitcode_sse2_x2, builtins_bitcode_sse2_x2_length, AddBitcodeToModule(builtins_bitcode_sse2_x2, builtins_bitcode_sse2_x2_length,
module, symbolTable); module, symbolTable);
break; break;
default: default:
@@ -810,14 +810,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
extern unsigned char builtins_bitcode_sse4_x2[]; extern unsigned char builtins_bitcode_sse4_x2[];
extern int builtins_bitcode_sse4_x2_length; extern int builtins_bitcode_sse4_x2_length;
switch (g->target.vectorWidth) { switch (g->target.vectorWidth) {
case 4: case 4:
AddBitcodeToModule(builtins_bitcode_sse4, AddBitcodeToModule(builtins_bitcode_sse4,
builtins_bitcode_sse4_length, builtins_bitcode_sse4_length,
module, symbolTable); module, symbolTable);
break; break;
case 8: case 8:
AddBitcodeToModule(builtins_bitcode_sse4_x2, AddBitcodeToModule(builtins_bitcode_sse4_x2,
builtins_bitcode_sse4_x2_length, builtins_bitcode_sse4_x2_length,
module, symbolTable); module, symbolTable);
break; break;
default: default:
@@ -829,14 +829,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
case 8: case 8:
extern unsigned char builtins_bitcode_avx1[]; extern unsigned char builtins_bitcode_avx1[];
extern int builtins_bitcode_avx1_length; extern int builtins_bitcode_avx1_length;
AddBitcodeToModule(builtins_bitcode_avx1, AddBitcodeToModule(builtins_bitcode_avx1,
builtins_bitcode_avx1_length, builtins_bitcode_avx1_length,
module, symbolTable); module, symbolTable);
break; break;
case 16: case 16:
extern unsigned char builtins_bitcode_avx1_x2[]; extern unsigned char builtins_bitcode_avx1_x2[];
extern int builtins_bitcode_avx1_x2_length; extern int builtins_bitcode_avx1_x2_length;
AddBitcodeToModule(builtins_bitcode_avx1_x2, AddBitcodeToModule(builtins_bitcode_avx1_x2,
builtins_bitcode_avx1_x2_length, builtins_bitcode_avx1_x2_length,
module, symbolTable); module, symbolTable);
break; break;
@@ -849,14 +849,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
case 8: case 8:
extern unsigned char builtins_bitcode_avx11[]; extern unsigned char builtins_bitcode_avx11[];
extern int builtins_bitcode_avx11_length; extern int builtins_bitcode_avx11_length;
AddBitcodeToModule(builtins_bitcode_avx11, AddBitcodeToModule(builtins_bitcode_avx11,
builtins_bitcode_avx11_length, builtins_bitcode_avx11_length,
module, symbolTable); module, symbolTable);
break; break;
case 16: case 16:
extern unsigned char builtins_bitcode_avx11_x2[]; extern unsigned char builtins_bitcode_avx11_x2[];
extern int builtins_bitcode_avx11_x2_length; extern int builtins_bitcode_avx11_x2_length;
AddBitcodeToModule(builtins_bitcode_avx11_x2, AddBitcodeToModule(builtins_bitcode_avx11_x2,
builtins_bitcode_avx11_x2_length, builtins_bitcode_avx11_x2_length,
module, symbolTable); module, symbolTable);
break; break;
@@ -869,14 +869,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
case 8: case 8:
extern unsigned char builtins_bitcode_avx2[]; extern unsigned char builtins_bitcode_avx2[];
extern int builtins_bitcode_avx2_length; extern int builtins_bitcode_avx2_length;
AddBitcodeToModule(builtins_bitcode_avx2, AddBitcodeToModule(builtins_bitcode_avx2,
builtins_bitcode_avx2_length, builtins_bitcode_avx2_length,
module, symbolTable); module, symbolTable);
break; break;
case 16: case 16:
extern unsigned char builtins_bitcode_avx2_x2[]; extern unsigned char builtins_bitcode_avx2_x2[];
extern int builtins_bitcode_avx2_x2_length; extern int builtins_bitcode_avx2_x2_length;
AddBitcodeToModule(builtins_bitcode_avx2_x2, AddBitcodeToModule(builtins_bitcode_avx2_x2,
builtins_bitcode_avx2_x2_length, builtins_bitcode_avx2_x2_length,
module, symbolTable); module, symbolTable);
break; break;
@@ -889,43 +889,43 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
case 4: case 4:
extern unsigned char builtins_bitcode_generic_4[]; extern unsigned char builtins_bitcode_generic_4[];
extern int builtins_bitcode_generic_4_length; extern int builtins_bitcode_generic_4_length;
AddBitcodeToModule(builtins_bitcode_generic_4, AddBitcodeToModule(builtins_bitcode_generic_4,
builtins_bitcode_generic_4_length, builtins_bitcode_generic_4_length,
module, symbolTable); module, symbolTable);
break; break;
case 8: case 8:
extern unsigned char builtins_bitcode_generic_8[]; extern unsigned char builtins_bitcode_generic_8[];
extern int builtins_bitcode_generic_8_length; extern int builtins_bitcode_generic_8_length;
AddBitcodeToModule(builtins_bitcode_generic_8, AddBitcodeToModule(builtins_bitcode_generic_8,
builtins_bitcode_generic_8_length, builtins_bitcode_generic_8_length,
module, symbolTable); module, symbolTable);
break; break;
case 16: case 16:
extern unsigned char builtins_bitcode_generic_16[]; extern unsigned char builtins_bitcode_generic_16[];
extern int builtins_bitcode_generic_16_length; extern int builtins_bitcode_generic_16_length;
AddBitcodeToModule(builtins_bitcode_generic_16, AddBitcodeToModule(builtins_bitcode_generic_16,
builtins_bitcode_generic_16_length, builtins_bitcode_generic_16_length,
module, symbolTable); module, symbolTable);
break; break;
case 32: case 32:
extern unsigned char builtins_bitcode_generic_32[]; extern unsigned char builtins_bitcode_generic_32[];
extern int builtins_bitcode_generic_32_length; extern int builtins_bitcode_generic_32_length;
AddBitcodeToModule(builtins_bitcode_generic_32, AddBitcodeToModule(builtins_bitcode_generic_32,
builtins_bitcode_generic_32_length, builtins_bitcode_generic_32_length,
module, symbolTable); module, symbolTable);
break; break;
case 64: case 64:
extern unsigned char builtins_bitcode_generic_64[]; extern unsigned char builtins_bitcode_generic_64[];
extern int builtins_bitcode_generic_64_length; extern int builtins_bitcode_generic_64_length;
AddBitcodeToModule(builtins_bitcode_generic_64, AddBitcodeToModule(builtins_bitcode_generic_64,
builtins_bitcode_generic_64_length, builtins_bitcode_generic_64_length,
module, symbolTable); module, symbolTable);
break; break;
case 1: case 1:
extern unsigned char builtins_bitcode_generic_1[]; extern unsigned char builtins_bitcode_generic_1[];
extern int builtins_bitcode_generic_1_length; extern int builtins_bitcode_generic_1_length;
AddBitcodeToModule(builtins_bitcode_generic_1, AddBitcodeToModule(builtins_bitcode_generic_1,
builtins_bitcode_generic_1_length, builtins_bitcode_generic_1_length,
module, symbolTable); module, symbolTable);
break; break;
default: default:
@@ -947,7 +947,7 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
lDefineConstantInt("__math_lib", (int)g->mathLib, module, symbolTable); lDefineConstantInt("__math_lib", (int)g->mathLib, module, symbolTable);
lDefineConstantInt("__math_lib_ispc", (int)Globals::Math_ISPC, module, lDefineConstantInt("__math_lib_ispc", (int)Globals::Math_ISPC, module,
symbolTable); symbolTable);
lDefineConstantInt("__math_lib_ispc_fast", (int)Globals::Math_ISPCFast, lDefineConstantInt("__math_lib_ispc_fast", (int)Globals::Math_ISPCFast,
module, symbolTable); module, symbolTable);
lDefineConstantInt("__math_lib_svml", (int)Globals::Math_SVML, module, lDefineConstantInt("__math_lib_svml", (int)Globals::Math_SVML, module,
symbolTable); symbolTable);
@@ -956,9 +956,9 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
lDefineConstantIntFunc("__fast_masked_vload", (int)g->opt.fastMaskedVload, lDefineConstantIntFunc("__fast_masked_vload", (int)g->opt.fastMaskedVload,
module, symbolTable); module, symbolTable);
lDefineConstantInt("__have_native_half", g->target.hasHalf, module, lDefineConstantInt("__have_native_half", g->target.hasHalf, module,
symbolTable); symbolTable);
lDefineConstantInt("__have_native_rand", g->target.hasRand, module, lDefineConstantInt("__have_native_rand", g->target.hasRand, module,
symbolTable); symbolTable);
lDefineConstantInt("__have_native_transcendentals", g->target.hasTranscendentals, lDefineConstantInt("__have_native_transcendentals", g->target.hasTranscendentals,
module, symbolTable); module, symbolTable);

View File

@@ -28,11 +28,11 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file builtins.h /** @file builtins.h
@brief Declarations of functions related to builtins and the @brief Declarations of functions related to builtins and the
standard library standard library
*/ */

View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file builtins-c.c /** @file builtins-c.c
@@ -101,12 +101,12 @@ typedef int Bool;
@param format Print format string @param format Print format string
@param types Encoded types of the values being printed. @param types Encoded types of the values being printed.
(See lEncodeType()). (See lEncodeType()).
@param width Vector width of the compilation target @param width Vector width of the compilation target
@param mask Current lane mask when the print statemnt is called @param mask Current lane mask when the print statemnt is called
@param args Array of pointers to the values to be printed @param args Array of pointers to the values to be printed
*/ */
void __do_print(const char *format, const char *types, int width, uint64_t mask, void __do_print(const char *format, const char *types, int width, uint64_t mask,
void **args) { void **args) {
char printString[PRINT_BUF_SIZE+1]; // +1 for trailing NUL char printString[PRINT_BUF_SIZE+1]; // +1 for trailing NUL
char *bufp = &printString[0]; char *bufp = &printString[0];

View File

@@ -119,12 +119,12 @@ namespace {
// objects, we keep several helper maps. // objects, we keep several helper maps.
llvm::DenseSet<const llvm::Value*> VisitedConstants; llvm::DenseSet<const llvm::Value*> VisitedConstants;
llvm::DenseSet<llvm::Type*> VisitedTypes; llvm::DenseSet<llvm::Type*> VisitedTypes;
std::vector<llvm::ArrayType*> &ArrayTypes; std::vector<llvm::ArrayType*> &ArrayTypes;
public: public:
TypeFinder(std::vector<llvm::ArrayType*> &t) TypeFinder(std::vector<llvm::ArrayType*> &t)
: ArrayTypes(t) {} : ArrayTypes(t) {}
void run(const llvm::Module &M) { void run(const llvm::Module &M) {
// Get types from global variables. // Get types from global variables.
for (llvm::Module::const_global_iterator I = M.global_begin(), for (llvm::Module::const_global_iterator I = M.global_begin(),
@@ -133,7 +133,7 @@ namespace {
if (I->hasInitializer()) if (I->hasInitializer())
incorporateValue(I->getInitializer()); incorporateValue(I->getInitializer());
} }
// Get types from aliases. // Get types from aliases.
for (llvm::Module::const_alias_iterator I = M.alias_begin(), for (llvm::Module::const_alias_iterator I = M.alias_begin(),
E = M.alias_end(); I != E; ++I) { E = M.alias_end(); I != E; ++I) {
@@ -141,13 +141,13 @@ namespace {
if (const llvm::Value *Aliasee = I->getAliasee()) if (const llvm::Value *Aliasee = I->getAliasee())
incorporateValue(Aliasee); incorporateValue(Aliasee);
} }
llvm::SmallVector<std::pair<unsigned, llvm::MDNode*>, 4> MDForInst; llvm::SmallVector<std::pair<unsigned, llvm::MDNode*>, 4> MDForInst;
// Get types from functions. // Get types from functions.
for (llvm::Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) { for (llvm::Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
incorporateType(FI->getType()); incorporateType(FI->getType());
for (llvm::Function::const_iterator BB = FI->begin(), E = FI->end(); for (llvm::Function::const_iterator BB = FI->begin(), E = FI->end();
BB != E;++BB) BB != E;++BB)
for (llvm::BasicBlock::const_iterator II = BB->begin(), for (llvm::BasicBlock::const_iterator II = BB->begin(),
@@ -158,13 +158,13 @@ namespace {
// Seems like there ought to be better way to do what we // Seems like there ought to be better way to do what we
// want here. For now, punt on SwitchInsts. // want here. For now, punt on SwitchInsts.
if (llvm::isa<llvm::SwitchInst>(&I)) continue; if (llvm::isa<llvm::SwitchInst>(&I)) continue;
// Incorporate the type of the instruction and all its operands. // Incorporate the type of the instruction and all its operands.
incorporateType(I.getType()); incorporateType(I.getType());
for (llvm::User::const_op_iterator OI = I.op_begin(), OE = I.op_end(); for (llvm::User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
OI != OE; ++OI) OI != OE; ++OI)
incorporateValue(*OI); incorporateValue(*OI);
// Incorporate types hiding in metadata. // Incorporate types hiding in metadata.
I.getAllMetadataOtherThanDebugLoc(MDForInst); I.getAllMetadataOtherThanDebugLoc(MDForInst);
for (unsigned i = 0, e = MDForInst.size(); i != e; ++i) for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
@@ -172,7 +172,7 @@ namespace {
MDForInst.clear(); MDForInst.clear();
} }
} }
for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(), for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(),
E = M.named_metadata_end(); I != E; ++I) { E = M.named_metadata_end(); I != E; ++I) {
const llvm::NamedMDNode *NMD = I; const llvm::NamedMDNode *NMD = I;
@@ -180,7 +180,7 @@ namespace {
incorporateMDNode(NMD->getOperand(i)); incorporateMDNode(NMD->getOperand(i));
} }
} }
private: private:
void incorporateType(llvm::Type *Ty) { void incorporateType(llvm::Type *Ty) {
// Check to see if we're already visited this type. // Check to see if we're already visited this type.
@@ -189,13 +189,13 @@ namespace {
if (llvm::ArrayType *ATy = llvm::dyn_cast<llvm::ArrayType>(Ty)) if (llvm::ArrayType *ATy = llvm::dyn_cast<llvm::ArrayType>(Ty))
ArrayTypes.push_back(ATy); ArrayTypes.push_back(ATy);
// Recursively walk all contained types. // Recursively walk all contained types.
for (llvm::Type::subtype_iterator I = Ty->subtype_begin(), for (llvm::Type::subtype_iterator I = Ty->subtype_begin(),
E = Ty->subtype_end(); I != E; ++I) E = Ty->subtype_end(); I != E; ++I)
incorporateType(*I); incorporateType(*I);
} }
/// incorporateValue - This method is used to walk operand lists finding /// incorporateValue - This method is used to walk operand lists finding
/// types hiding in constant expressions and other operands that won't be /// types hiding in constant expressions and other operands that won't be
/// walked in other ways. GlobalValues, basic blocks, instructions, and /// walked in other ways. GlobalValues, basic blocks, instructions, and
@@ -204,27 +204,27 @@ namespace {
if (const llvm::MDNode *M = llvm::dyn_cast<llvm::MDNode>(V)) if (const llvm::MDNode *M = llvm::dyn_cast<llvm::MDNode>(V))
return incorporateMDNode(M); return incorporateMDNode(M);
if (!llvm::isa<llvm::Constant>(V) || llvm::isa<llvm::GlobalValue>(V)) return; if (!llvm::isa<llvm::Constant>(V) || llvm::isa<llvm::GlobalValue>(V)) return;
// Already visited? // Already visited?
if (!VisitedConstants.insert(V).second) if (!VisitedConstants.insert(V).second)
return; return;
// Check this type. // Check this type.
incorporateType(V->getType()); incorporateType(V->getType());
// Look in operands for types. // Look in operands for types.
const llvm::User *U = llvm::cast<llvm::User>(V); const llvm::User *U = llvm::cast<llvm::User>(V);
for (llvm::Constant::const_op_iterator I = U->op_begin(), for (llvm::Constant::const_op_iterator I = U->op_begin(),
E = U->op_end(); I != E;++I) E = U->op_end(); I != E;++I)
incorporateValue(*I); incorporateValue(*I);
} }
void incorporateMDNode(const llvm::MDNode *V) { void incorporateMDNode(const llvm::MDNode *V) {
// Already visited? // Already visited?
if (!VisitedConstants.insert(V).second) if (!VisitedConstants.insert(V).second)
return; return;
// Look in operands for types. // Look in operands for types.
for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i) for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i)
if (llvm::Value *Op = V->getOperand(i)) if (llvm::Value *Op = V->getOperand(i))
@@ -266,7 +266,7 @@ namespace {
// TargetData have generally similar interfaces... // TargetData have generally similar interfaces...
const llvm::DataLayout* TD; const llvm::DataLayout* TD;
#endif #endif
std::map<const llvm::ConstantFP *, unsigned> FPConstantMap; std::map<const llvm::ConstantFP *, unsigned> FPConstantMap;
std::map<const llvm::ConstantDataVector *, unsigned> VectorConstantMap; std::map<const llvm::ConstantDataVector *, unsigned> VectorConstantMap;
unsigned VectorConstantIndex; unsigned VectorConstantIndex;
@@ -276,7 +276,7 @@ namespace {
unsigned OpaqueCounter; unsigned OpaqueCounter;
llvm::DenseMap<const llvm::Value*, unsigned> AnonValueNumbers; llvm::DenseMap<const llvm::Value*, unsigned> AnonValueNumbers;
unsigned NextAnonValueNumber; unsigned NextAnonValueNumber;
std::string includeName; std::string includeName;
int vectorWidth; int vectorWidth;
@@ -291,7 +291,7 @@ namespace {
int vecwidth) int vecwidth)
: FunctionPass(ID), Out(o), IL(0), /* Mang(0), */ LI(0), : FunctionPass(ID), Out(o), IL(0), /* Mang(0), */ LI(0),
TheModule(0), TAsm(0), MRI(0), MOFI(0), TCtx(0), TD(0), TheModule(0), TAsm(0), MRI(0), MOFI(0), TCtx(0), TD(0),
OpaqueCounter(0), NextAnonValueNumber(0), OpaqueCounter(0), NextAnonValueNumber(0),
includeName(incname ? incname : "generic_defs.h"), includeName(incname ? incname : "generic_defs.h"),
vectorWidth(vecwidth) { vectorWidth(vecwidth) {
initializeLoopInfoPass(*llvm::PassRegistry::getPassRegistry()); initializeLoopInfoPass(*llvm::PassRegistry::getPassRegistry());
@@ -372,7 +372,7 @@ namespace {
std::string getStructName(llvm::StructType *ST); std::string getStructName(llvm::StructType *ST);
std::string getArrayName(llvm::ArrayType *AT); std::string getArrayName(llvm::ArrayType *AT);
/// writeOperandDeref - Print the result of dereferencing the specified /// writeOperandDeref - Print the result of dereferencing the specified
/// operand with '*'. This is equivalent to printing '*' then using /// operand with '*'. This is equivalent to printing '*' then using
/// writeOperand, but avoids excess syntax in some cases. /// writeOperand, but avoids excess syntax in some cases.
@@ -399,7 +399,7 @@ namespace {
private : private :
void lowerIntrinsics(llvm::Function &F); void lowerIntrinsics(llvm::Function &F);
/// Prints the definition of the intrinsic function F. Supports the /// Prints the definition of the intrinsic function F. Supports the
/// intrinsics which need to be explicitly defined in the CBackend. /// intrinsics which need to be explicitly defined in the CBackend.
void printIntrinsicDefinition(const llvm::Function &F, llvm::raw_ostream &Out); void printIntrinsicDefinition(const llvm::Function &F, llvm::raw_ostream &Out);
@@ -573,7 +573,7 @@ static std::string CBEMangle(const std::string &S) {
std::string CWriter::getStructName(llvm::StructType *ST) { std::string CWriter::getStructName(llvm::StructType *ST) {
if (!ST->isLiteral() && !ST->getName().empty()) if (!ST->isLiteral() && !ST->getName().empty())
return CBEMangle("l_"+ST->getName().str()); return CBEMangle("l_"+ST->getName().str());
return "l_unnamed_" + llvm::utostr(UnnamedStructIDs[ST]); return "l_unnamed_" + llvm::utostr(UnnamedStructIDs[ST]);
} }
@@ -694,19 +694,19 @@ CWriter::printSimpleType(llvm::raw_ostream &Out, llvm::Type *Ty, bool isSigned,
assert(eltTy->isIntegerTy()); assert(eltTy->isIntegerTy());
switch (eltTy->getPrimitiveSizeInBits()) { switch (eltTy->getPrimitiveSizeInBits()) {
case 1: case 1:
suffix = "i1"; suffix = "i1";
break; break;
case 8: case 8:
suffix = "i8"; suffix = "i8";
break; break;
case 16: case 16:
suffix = "i16"; suffix = "i16";
break; break;
case 32: case 32:
suffix = "i32"; suffix = "i32";
break; break;
case 64: case 64:
suffix = "i64"; suffix = "i64";
break; break;
default: default:
llvm::report_fatal_error("Only integer types of size 8/16/32/64 are " llvm::report_fatal_error("Only integer types of size 8/16/32/64 are "
@@ -714,7 +714,7 @@ CWriter::printSimpleType(llvm::raw_ostream &Out, llvm::Type *Ty, bool isSigned,
} }
} }
return Out << "__vec" << VTy->getNumElements() << "_" << suffix << " " << return Out << "__vec" << VTy->getNumElements() << "_" << suffix << " " <<
NameSoFar; NameSoFar;
#else #else
return printSimpleType(Out, VTy->getElementType(), isSigned, return printSimpleType(Out, VTy->getElementType(), isSigned,
@@ -736,7 +736,7 @@ CWriter::printSimpleType(llvm::raw_ostream &Out, llvm::Type *Ty, bool isSigned,
// //
llvm::raw_ostream &CWriter::printType(llvm::raw_ostream &Out, llvm::Type *Ty, llvm::raw_ostream &CWriter::printType(llvm::raw_ostream &Out, llvm::Type *Ty,
bool isSigned, const std::string &NameSoFar, bool isSigned, const std::string &NameSoFar,
bool IgnoreName, bool IgnoreName,
#if defined(LLVM_3_1) || defined(LLVM_3_2) #if defined(LLVM_3_1) || defined(LLVM_3_2)
const llvm::AttrListPtr &PAL const llvm::AttrListPtr &PAL
#else #else
@@ -803,11 +803,11 @@ llvm::raw_ostream &CWriter::printType(llvm::raw_ostream &Out, llvm::Type *Ty,
} }
case llvm::Type::StructTyID: { case llvm::Type::StructTyID: {
llvm::StructType *STy = llvm::cast<llvm::StructType>(Ty); llvm::StructType *STy = llvm::cast<llvm::StructType>(Ty);
// Check to see if the type is named. // Check to see if the type is named.
if (!IgnoreName) if (!IgnoreName)
return Out << getStructName(STy) << ' ' << NameSoFar; return Out << getStructName(STy) << ' ' << NameSoFar;
Out << "struct " << NameSoFar << " {\n"; Out << "struct " << NameSoFar << " {\n";
// print initialization func // print initialization func
@@ -930,13 +930,13 @@ void CWriter::printConstantDataSequential(llvm::ConstantDataSequential *CDS,
Out << '\"'; Out << '\"';
// Keep track of whether the last number was a hexadecimal escape. // Keep track of whether the last number was a hexadecimal escape.
bool LastWasHex = false; bool LastWasHex = false;
llvm::StringRef Bytes = CDS->getAsCString(); llvm::StringRef Bytes = CDS->getAsCString();
// Do not include the last character, which we know is null // Do not include the last character, which we know is null
for (unsigned i = 0, e = Bytes.size(); i != e; ++i) { for (unsigned i = 0, e = Bytes.size(); i != e; ++i) {
unsigned char C = Bytes[i]; unsigned char C = Bytes[i];
// Print it out literally if it is a printable character. The only thing // Print it out literally if it is a printable character. The only thing
// to be careful about is when the last letter output was a hex escape // to be careful about is when the last letter output was a hex escape
// code, in which case we have to be careful not to print out hex digits // code, in which case we have to be careful not to print out hex digits
@@ -1143,8 +1143,8 @@ bool CWriter::printCast(unsigned opc, llvm::Type *SrcTy, llvm::Type *DstTy) {
/** Construct the name of a function with the given base and returning a /** Construct the name of a function with the given base and returning a
vector of a given type, of the specified idth. For example, if base vector of a given type, of the specified idth. For example, if base
is "foo" and matchType is i32 and width is 16, this will return the is "foo" and matchType is i32 and width is 16, this will return the
string "__foo_i32<__vec16_i32>". string "__foo_i32<__vec16_i32>".
*/ */
static const char * static const char *
@@ -1492,7 +1492,7 @@ void CWriter::printConstant(llvm::Constant *CPV, bool Static) {
} }
if (llvm::ConstantArray *CA = llvm::dyn_cast<llvm::ConstantArray>(CPV)) { if (llvm::ConstantArray *CA = llvm::dyn_cast<llvm::ConstantArray>(CPV)) {
printConstantArray(CA, Static); printConstantArray(CA, Static);
} else if (llvm::ConstantDataSequential *CDS = } else if (llvm::ConstantDataSequential *CDS =
llvm::dyn_cast<llvm::ConstantDataSequential>(CPV)) { llvm::dyn_cast<llvm::ConstantDataSequential>(CPV)) {
printConstantDataSequential(CDS, Static); printConstantDataSequential(CDS, Static);
} else { } else {
@@ -1584,7 +1584,7 @@ void CWriter::printConstant(llvm::Constant *CPV, bool Static) {
llvm::report_fatal_error("Unexpected vector type"); llvm::report_fatal_error("Unexpected vector type");
} }
} }
break; break;
} }
case llvm::Type::StructTyID: case llvm::Type::StructTyID:
@@ -2658,7 +2658,7 @@ void CWriter::printModuleTypes() {
Out << "/* Structure and array forward declarations */\n"; Out << "/* Structure and array forward declarations */\n";
unsigned NextTypeID = 0; unsigned NextTypeID = 0;
// If any of them are missing names, add a unique ID to UnnamedStructIDs. // If any of them are missing names, add a unique ID to UnnamedStructIDs.
// Print out forward declarations for structure types. // Print out forward declarations for structure types.
for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) { for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) {
@@ -2718,7 +2718,7 @@ void CWriter::printContainedStructs(llvm::Type *Ty,
if (llvm::StructType *ST = llvm::dyn_cast<llvm::StructType>(Ty)) { if (llvm::StructType *ST = llvm::dyn_cast<llvm::StructType>(Ty)) {
// Check to see if we have already printed this struct. // Check to see if we have already printed this struct.
if (!Printed.insert(Ty)) return; if (!Printed.insert(Ty)) return;
// Print structure type out. // Print structure type out.
printType(Out, ST, false, getStructName(ST), true); printType(Out, ST, false, getStructName(ST), true);
Out << ";\n\n"; Out << ";\n\n";
@@ -3623,8 +3623,8 @@ void CWriter::printIntrinsicDefinition(const llvm::Function &F, llvm::raw_ostrea
Out << " r.field1 = (r.field0 < a);\n"; Out << " r.field1 = (r.field0 < a);\n";
Out << " return r;\n}\n"; Out << " return r;\n}\n";
break; break;
case llvm::Intrinsic::sadd_with_overflow: case llvm::Intrinsic::sadd_with_overflow:
// static inline Rty sadd_ixx(ixx a, ixx b) { // static inline Rty sadd_ixx(ixx a, ixx b) {
// Rty r; // Rty r;
// r.field1 = (b > 0 && a > XX_MAX - b) || // r.field1 = (b > 0 && a > XX_MAX - b) ||
@@ -3851,10 +3851,10 @@ void CWriter::visitCallInst(llvm::CallInst &I) {
Out << ')'; Out << ')';
} }
// Check if the argument is expected to be passed by value. // Check if the argument is expected to be passed by value.
if (I.paramHasAttr(ArgNo+1, if (I.paramHasAttr(ArgNo+1,
#if defined(LLVM_3_2) #if defined(LLVM_3_2)
llvm::Attributes::ByVal llvm::Attributes::ByVal
#else #else
llvm::Attribute::ByVal llvm::Attribute::ByVal
#endif #endif
)) ))
@@ -4419,7 +4419,7 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
restart: restart:
for (llvm::BasicBlock::iterator iter = bb.begin(), e = bb.end(); iter != e; ++iter) { for (llvm::BasicBlock::iterator iter = bb.begin(), e = bb.end(); iter != e; ++iter) {
llvm::InsertElementInst *insertInst = llvm::InsertElementInst *insertInst =
llvm::dyn_cast<llvm::InsertElementInst>(&*iter); llvm::dyn_cast<llvm::InsertElementInst>(&*iter);
if (insertInst == NULL) if (insertInst == NULL)
continue; continue;
@@ -4444,7 +4444,7 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
else if (toMatch != insertValue) else if (toMatch != insertValue)
goto not_equal; goto not_equal;
insertInst = insertInst =
llvm::dyn_cast<llvm::InsertElementInst>(insertInst->getOperand(0)); llvm::dyn_cast<llvm::InsertElementInst>(insertInst->getOperand(0));
} }
assert(toMatch != NULL); assert(toMatch != NULL);
@@ -4458,8 +4458,8 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
// Declare the smear function if needed; it takes a single // Declare the smear function if needed; it takes a single
// scalar parameter and returns a vector of the same // scalar parameter and returns a vector of the same
// parameter type. // parameter type.
llvm::Constant *sf = llvm::Constant *sf =
module->getOrInsertFunction(smearFuncName, iter->getType(), module->getOrInsertFunction(smearFuncName, iter->getType(),
matchType, NULL); matchType, NULL);
smearFunc = llvm::dyn_cast<llvm::Function>(sf); smearFunc = llvm::dyn_cast<llvm::Function>(sf);
assert(smearFunc != NULL); assert(smearFunc != NULL);
@@ -4475,7 +4475,7 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
assert(smearFunc != NULL); assert(smearFunc != NULL);
llvm::Value *args[1] = { toMatch }; llvm::Value *args[1] = { toMatch };
llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[1]); llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[1]);
llvm::Instruction *smearCall = llvm::Instruction *smearCall =
llvm::CallInst::Create(smearFunc, argArray, LLVMGetName(toMatch, "_smear"), llvm::CallInst::Create(smearFunc, argArray, LLVMGetName(toMatch, "_smear"),
(llvm::Instruction *)NULL); (llvm::Instruction *)NULL);
@@ -4608,9 +4608,9 @@ AndCmpCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
// are the same as the two arguments to the compare we're // are the same as the two arguments to the compare we're
// replacing and the third argument is the mask type. // replacing and the third argument is the mask type.
llvm::Type *cmpOpType = opCmp->getOperand(0)->getType(); llvm::Type *cmpOpType = opCmp->getOperand(0)->getType();
llvm::Constant *acf = llvm::Constant *acf =
m->module->getOrInsertFunction(funcName, LLVMTypes::MaskType, m->module->getOrInsertFunction(funcName, LLVMTypes::MaskType,
cmpOpType, cmpOpType, cmpOpType, cmpOpType,
LLVMTypes::MaskType, NULL); LLVMTypes::MaskType, NULL);
andCmpFunc = llvm::dyn_cast<llvm::Function>(acf); andCmpFunc = llvm::dyn_cast<llvm::Function>(acf);
Assert(andCmpFunc != NULL); Assert(andCmpFunc != NULL);
@@ -4625,11 +4625,11 @@ AndCmpCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
// Set up the function call to the *_and_mask function; the // Set up the function call to the *_and_mask function; the
// mask value passed in is the other operand to the AND. // mask value passed in is the other operand to the AND.
llvm::Value *args[3] = { opCmp->getOperand(0), opCmp->getOperand(1), llvm::Value *args[3] = { opCmp->getOperand(0), opCmp->getOperand(1),
bop->getOperand(i ^ 1) }; bop->getOperand(i ^ 1) };
llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[3]); llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[3]);
llvm::Instruction *cmpCall = llvm::Instruction *cmpCall =
llvm::CallInst::Create(andCmpFunc, argArray, llvm::CallInst::Create(andCmpFunc, argArray,
LLVMGetName(bop, "_and_mask"), LLVMGetName(bop, "_and_mask"),
(llvm::Instruction *)NULL); (llvm::Instruction *)NULL);
@@ -4656,12 +4656,12 @@ AndCmpCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
class MaskOpsCleanupPass : public llvm::BasicBlockPass { class MaskOpsCleanupPass : public llvm::BasicBlockPass {
public: public:
MaskOpsCleanupPass(llvm::Module *m) MaskOpsCleanupPass(llvm::Module *m)
: BasicBlockPass(ID) { : BasicBlockPass(ID) {
llvm::Type *mt = LLVMTypes::MaskType; llvm::Type *mt = LLVMTypes::MaskType;
// Declare the __not, __and_not1, and __and_not2 functions that we // Declare the __not, __and_not1, and __and_not2 functions that we
// expect the target to end up providing. // expect the target to end up providing.
notFunc = notFunc =
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__not", mt, mt, NULL)); llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__not", mt, mt, NULL));
assert(notFunc != NULL); assert(notFunc != NULL);
#if defined(LLVM_3_2) #if defined(LLVM_3_2)
@@ -4672,7 +4672,7 @@ public:
notFunc->addFnAttr(llvm::Attribute::ReadNone); notFunc->addFnAttr(llvm::Attribute::ReadNone);
#endif #endif
andNotFuncs[0] = andNotFuncs[0] =
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not1", mt, mt, mt, llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not1", mt, mt, mt,
NULL)); NULL));
assert(andNotFuncs[0] != NULL); assert(andNotFuncs[0] != NULL);
@@ -4683,7 +4683,7 @@ public:
andNotFuncs[0]->addFnAttr(llvm::Attribute::NoUnwind); andNotFuncs[0]->addFnAttr(llvm::Attribute::NoUnwind);
andNotFuncs[0]->addFnAttr(llvm::Attribute::ReadNone); andNotFuncs[0]->addFnAttr(llvm::Attribute::ReadNone);
#endif #endif
andNotFuncs[1] = andNotFuncs[1] =
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not2", mt, mt, mt, llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not2", mt, mt, mt,
NULL)); NULL));
assert(andNotFuncs[1] != NULL); assert(andNotFuncs[1] != NULL);
@@ -4711,7 +4711,7 @@ char MaskOpsCleanupPass::ID = 0;
/** Returns true if the given value is a compile-time constant vector of /** Returns true if the given value is a compile-time constant vector of
i1s with all elements 'true'. i1s with all elements 'true'.
*/ */
static bool static bool
lIsAllTrue(llvm::Value *v) { lIsAllTrue(llvm::Value *v) {
@@ -4721,7 +4721,7 @@ lIsAllTrue(llvm::Value *v) {
(ci = llvm::dyn_cast<llvm::ConstantInt>(cv->getSplatValue())) != NULL && (ci = llvm::dyn_cast<llvm::ConstantInt>(cv->getSplatValue())) != NULL &&
ci->isOne()); ci->isOne());
} }
if (llvm::ConstantDataVector *cdv = llvm::dyn_cast<llvm::ConstantDataVector>(v)) { if (llvm::ConstantDataVector *cdv = llvm::dyn_cast<llvm::ConstantDataVector>(v)) {
llvm::ConstantInt *ci; llvm::ConstantInt *ci;
return (cdv->getSplatValue() != NULL && return (cdv->getSplatValue() != NULL &&
@@ -4770,7 +4770,7 @@ MaskOpsCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
// Check for XOR with all-true values // Check for XOR with all-true values
if (lIsAllTrue(bop->getOperand(1))) { if (lIsAllTrue(bop->getOperand(1))) {
llvm::ArrayRef<llvm::Value *> arg(bop->getOperand(0)); llvm::ArrayRef<llvm::Value *> arg(bop->getOperand(0));
llvm::CallInst *notCall = llvm::CallInst::Create(notFunc, arg, llvm::CallInst *notCall = llvm::CallInst::Create(notFunc, arg,
bop->getName()); bop->getName());
ReplaceInstWithInst(iter, notCall); ReplaceInstWithInst(iter, notCall);
modifiedAny = true; modifiedAny = true;
@@ -4791,7 +4791,7 @@ MaskOpsCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
llvm::ArrayRef<llvm::Value *> argsRef(&args[0], 2); llvm::ArrayRef<llvm::Value *> argsRef(&args[0], 2);
// Call the appropriate __and_not* function. // Call the appropriate __and_not* function.
llvm::CallInst *andNotCall = llvm::CallInst *andNotCall =
llvm::CallInst::Create(andNotFuncs[i], argsRef, bop->getName()); llvm::CallInst::Create(andNotFuncs[i], argsRef, bop->getName());
ReplaceInstWithInst(iter, andNotCall); ReplaceInstWithInst(iter, andNotCall);

366
ctx.cpp

File diff suppressed because it is too large Load Diff

54
ctx.h
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file ctx.h /** @file ctx.h
@@ -75,7 +75,7 @@ public:
@param firstStmtPos Source file position of the first statement in the @param firstStmtPos Source file position of the first statement in the
function function
*/ */
FunctionEmitContext(Function *function, Symbol *funSym, FunctionEmitContext(Function *function, Symbol *funSym,
llvm::Function *llvmFunction, llvm::Function *llvmFunction,
SourcePos firstStmtPos); SourcePos firstStmtPos);
~FunctionEmitContext(); ~FunctionEmitContext();
@@ -87,9 +87,9 @@ public:
/** @name Current basic block management /** @name Current basic block management
@{ @{
*/ */
/** Returns the current basic block pointer */ /** Returns the current basic block pointer */
llvm::BasicBlock *GetCurrentBasicBlock(); llvm::BasicBlock *GetCurrentBasicBlock();
/** Set the given llvm::BasicBlock to be the basic block to emit /** Set the given llvm::BasicBlock to be the basic block to emit
forthcoming instructions into. */ forthcoming instructions into. */
void SetCurrentBasicBlock(llvm::BasicBlock *bblock); void SetCurrentBasicBlock(llvm::BasicBlock *bblock);
@@ -97,7 +97,7 @@ public:
/** @name Mask management /** @name Mask management
@{ @{
*/ */
/** Returns the mask value at entry to the current function. */ /** Returns the mask value at entry to the current function. */
llvm::Value *GetFunctionMask(); llvm::Value *GetFunctionMask();
/** Returns the mask value corresponding to "varying" control flow /** Returns the mask value corresponding to "varying" control flow
@@ -106,7 +106,7 @@ public:
llvm::Value *GetInternalMask(); llvm::Value *GetInternalMask();
/** Returns the complete current mask value--i.e. the logical AND of /** Returns the complete current mask value--i.e. the logical AND of
the function entry mask and the internal mask. */ the function entry mask and the internal mask. */
llvm::Value *GetFullMask(); llvm::Value *GetFullMask();
/** Returns a pointer to storage in memory that stores the current full /** Returns a pointer to storage in memory that stores the current full
@@ -159,7 +159,7 @@ public:
'continue' statements should jump to (if all running lanes want to 'continue' statements should jump to (if all running lanes want to
break or continue), uniformControlFlow indicates whether the loop break or continue), uniformControlFlow indicates whether the loop
condition is 'uniform'. */ condition is 'uniform'. */
void StartLoop(llvm::BasicBlock *breakTarget, llvm::BasicBlock *continueTarget, void StartLoop(llvm::BasicBlock *breakTarget, llvm::BasicBlock *continueTarget,
bool uniformControlFlow); bool uniformControlFlow);
/** Informs FunctionEmitContext of the value of the mask at the start /** Informs FunctionEmitContext of the value of the mask at the start
@@ -213,8 +213,8 @@ public:
@param caseBlocks vector that stores the mapping from label values @param caseBlocks vector that stores the mapping from label values
after "case" statements to basic blocks corresponding after "case" statements to basic blocks corresponding
to the "case" labels. to the "case" labels.
@param nextBlocks For each basic block for a "case" or "default" @param nextBlocks For each basic block for a "case" or "default"
label, this gives the basic block for the label, this gives the basic block for the
immediately-following "case" or "default" label (or immediately-following "case" or "default" label (or
the basic block after the "switch" statement for the the basic block after the "switch" statement for the
last label.) last label.)
@@ -272,7 +272,7 @@ public:
/** @} */ /** @} */
/** @name Small helper/utility routines /** @name Small helper/utility routines
@{ @{
*/ */
/** Given a boolean mask value of type LLVMTypes::MaskType, return an /** Given a boolean mask value of type LLVMTypes::MaskType, return an
i1 value that indicates if any of the mask lanes are on. */ i1 value that indicates if any of the mask lanes are on. */
@@ -332,7 +332,7 @@ public:
llvm::Instruction for convenience; in calling code we often have llvm::Instruction for convenience; in calling code we often have
Instructions stored using Value pointers; the code here returns Instructions stored using Value pointers; the code here returns
silently if it's not actually given an instruction. */ silently if it's not actually given an instruction. */
void AddDebugPos(llvm::Value *instruction, const SourcePos *pos = NULL, void AddDebugPos(llvm::Value *instruction, const SourcePos *pos = NULL,
llvm::DIScope *scope = NULL); llvm::DIScope *scope = NULL);
/** Inform the debugging information generation code that a new scope /** Inform the debugging information generation code that a new scope
@@ -361,7 +361,7 @@ public:
instructions. See the LLVM assembly language reference manual instructions. See the LLVM assembly language reference manual
(http://llvm.org/docs/LangRef.html) and the LLVM doxygen documentaion (http://llvm.org/docs/LangRef.html) and the LLVM doxygen documentaion
(http://llvm.org/doxygen) for more information. Here we will only (http://llvm.org/doxygen) for more information. Here we will only
document significant generalizations to the functionality of the document significant generalizations to the functionality of the
corresponding basic LLVM instructions. corresponding basic LLVM instructions.
Beyond actually emitting the instruction, the implementations of Beyond actually emitting the instruction, the implementations of
@@ -377,7 +377,7 @@ public:
this also handles applying the given operation to the vector this also handles applying the given operation to the vector
elements. */ elements. */
llvm::Value *BinaryOperator(llvm::Instruction::BinaryOps inst, llvm::Value *BinaryOperator(llvm::Instruction::BinaryOps inst,
llvm::Value *v0, llvm::Value *v1, llvm::Value *v0, llvm::Value *v1,
const char *name = NULL); const char *name = NULL);
/** Emit the "not" operator. Like BinaryOperator(), this also handles /** Emit the "not" operator. Like BinaryOperator(), this also handles
@@ -387,7 +387,7 @@ public:
/** Emit a comparison instruction. If the operands are VectorTypes, /** Emit a comparison instruction. If the operands are VectorTypes,
then a value for the corresponding boolean VectorType is then a value for the corresponding boolean VectorType is
returned. */ returned. */
llvm::Value *CmpInst(llvm::Instruction::OtherOps inst, llvm::Value *CmpInst(llvm::Instruction::OtherOps inst,
llvm::CmpInst::Predicate pred, llvm::CmpInst::Predicate pred,
llvm::Value *v0, llvm::Value *v1, const char *name = NULL); llvm::Value *v0, llvm::Value *v1, const char *name = NULL);
@@ -407,17 +407,17 @@ public:
const char *name = NULL); const char *name = NULL);
llvm::Instruction *CastInst(llvm::Instruction::CastOps op, llvm::Value *value, llvm::Instruction *CastInst(llvm::Instruction::CastOps op, llvm::Value *value,
llvm::Type *type, const char *name = NULL); llvm::Type *type, const char *name = NULL);
llvm::Instruction *FPCastInst(llvm::Value *value, llvm::Type *type, llvm::Instruction *FPCastInst(llvm::Value *value, llvm::Type *type,
const char *name = NULL); const char *name = NULL);
llvm::Instruction *SExtInst(llvm::Value *value, llvm::Type *type, llvm::Instruction *SExtInst(llvm::Value *value, llvm::Type *type,
const char *name = NULL); const char *name = NULL);
llvm::Instruction *ZExtInst(llvm::Value *value, llvm::Type *type, llvm::Instruction *ZExtInst(llvm::Value *value, llvm::Type *type,
const char *name = NULL); const char *name = NULL);
/** Given two integer-typed values (but possibly one vector and the /** Given two integer-typed values (but possibly one vector and the
other not, and or of possibly-different bit-widths), update their other not, and or of possibly-different bit-widths), update their
values as needed so that the two have the same (more general) values as needed so that the two have the same (more general)
type. */ type. */
void MatchIntegerTypes(llvm::Value **v0, llvm::Value **v1); void MatchIntegerTypes(llvm::Value **v0, llvm::Value **v1);
/** Create a new slice pointer out of the given pointer to an soa type /** Create a new slice pointer out of the given pointer to an soa type
@@ -462,9 +462,9 @@ public:
allocated at the given alignment. By default, the alloca allocated at the given alignment. By default, the alloca
instruction is added at the start of the function in the entry instruction is added at the start of the function in the entry
basic block; if it should be added to the current basic block, then basic block; if it should be added to the current basic block, then
the atEntryBlock parameter should be false. */ the atEntryBlock parameter should be false. */
llvm::Value *AllocaInst(llvm::Type *llvmType, llvm::Value *AllocaInst(llvm::Type *llvmType,
const char *name = NULL, int align = 0, const char *name = NULL, int align = 0,
bool atEntryBlock = true); bool atEntryBlock = true);
/** Standard store instruction; for this variant, the lvalue must be a /** Standard store instruction; for this variant, the lvalue must be a
@@ -481,7 +481,7 @@ public:
/** Copy count bytes of memory from the location pointed to by src to /** Copy count bytes of memory from the location pointed to by src to
the location pointed to by dest. (src and dest must not be the location pointed to by dest. (src and dest must not be
overlapping.) */ overlapping.) */
void MemcpyInst(llvm::Value *dest, llvm::Value *src, llvm::Value *count, void MemcpyInst(llvm::Value *dest, llvm::Value *src, llvm::Value *count,
llvm::Value *align = NULL); llvm::Value *align = NULL);
@@ -497,10 +497,10 @@ public:
/** This convenience method maps to an llvm::InsertElementInst if the /** This convenience method maps to an llvm::InsertElementInst if the
given value is a llvm::VectorType, and to an llvm::InsertValueInst given value is a llvm::VectorType, and to an llvm::InsertValueInst
otherwise. */ otherwise. */
llvm::Value *InsertInst(llvm::Value *v, llvm::Value *eltVal, int elt, llvm::Value *InsertInst(llvm::Value *v, llvm::Value *eltVal, int elt,
const char *name = NULL); const char *name = NULL);
llvm::PHINode *PhiNode(llvm::Type *type, int count, llvm::PHINode *PhiNode(llvm::Type *type, int count,
const char *name = NULL); const char *name = NULL);
llvm::Instruction *SelectInst(llvm::Value *test, llvm::Value *val0, llvm::Instruction *SelectInst(llvm::Value *test, llvm::Value *val0,
llvm::Value *val1, const char *name = NULL); llvm::Value *val1, const char *name = NULL);
@@ -526,7 +526,7 @@ public:
/** Launch an asynchronous task to run the given function, passing it /** Launch an asynchronous task to run the given function, passing it
he given argument values. */ he given argument values. */
llvm::Value *LaunchInst(llvm::Value *callee, llvm::Value *LaunchInst(llvm::Value *callee,
std::vector<llvm::Value *> &argVals, std::vector<llvm::Value *> &argVals,
llvm::Value *launchCount); llvm::Value *launchCount);
@@ -680,7 +680,7 @@ private:
void jumpIfAllLoopLanesAreDone(llvm::BasicBlock *target); void jumpIfAllLoopLanesAreDone(llvm::BasicBlock *target);
llvm::Value *emitGatherCallback(llvm::Value *lvalue, llvm::Value *retPtr); llvm::Value *emitGatherCallback(llvm::Value *lvalue, llvm::Value *retPtr);
llvm::Value *applyVaryingGEP(llvm::Value *basePtr, llvm::Value *index, llvm::Value *applyVaryingGEP(llvm::Value *basePtr, llvm::Value *index,
const Type *ptrType); const Type *ptrType);
void restoreMaskGivenReturns(llvm::Value *oldMask); void restoreMaskGivenReturns(llvm::Value *oldMask);
@@ -694,7 +694,7 @@ private:
const Type *ptrType, llvm::Value *mask); const Type *ptrType, llvm::Value *mask);
void maskedStore(llvm::Value *value, llvm::Value *ptr, const Type *ptrType, void maskedStore(llvm::Value *value, llvm::Value *ptr, const Type *ptrType,
llvm::Value *mask); llvm::Value *mask);
void storeUniformToSOA(llvm::Value *value, llvm::Value *ptr, void storeUniformToSOA(llvm::Value *value, llvm::Value *ptr,
llvm::Value *mask, const Type *valueType, llvm::Value *mask, const Type *valueType,
const PointerType *ptrType); const PointerType *ptrType);
llvm::Value *loadUniformFromSOA(llvm::Value *ptr, llvm::Value *mask, llvm::Value *loadUniformFromSOA(llvm::Value *ptr, llvm::Value *mask,

View File

@@ -28,11 +28,11 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file decl.cpp /** @file decl.cpp
@brief Implementations of classes related to turning declarations into @brief Implementations of classes related to turning declarations into
symbol names and types. symbol names and types.
*/ */
@@ -62,7 +62,7 @@ lPrintTypeQualifiers(int typeQualifiers) {
/** Given a Type and a set of type qualifiers, apply the type qualifiers to /** Given a Type and a set of type qualifiers, apply the type qualifiers to
the type, returning the type that is the result. the type, returning the type that is the result.
*/ */
static const Type * static const Type *
lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) { lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
@@ -97,7 +97,7 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
if (unsignedType != NULL) if (unsignedType != NULL)
type = unsignedType; type = unsignedType;
else { else {
const Type *resolvedType = const Type *resolvedType =
type->ResolveUnboundVariability(Variability::Varying); type->ResolveUnboundVariability(Variability::Varying);
Error(pos, "\"unsigned\" qualifier is illegal with \"%s\" type.", Error(pos, "\"unsigned\" qualifier is illegal with \"%s\" type.",
resolvedType->GetString().c_str()); resolvedType->GetString().c_str());
@@ -105,7 +105,7 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
} }
if ((typeQualifiers & TYPEQUAL_SIGNED) != 0 && type->IsIntType() == false) { if ((typeQualifiers & TYPEQUAL_SIGNED) != 0 && type->IsIntType() == false) {
const Type *resolvedType = const Type *resolvedType =
type->ResolveUnboundVariability(Variability::Varying); type->ResolveUnboundVariability(Variability::Varying);
Error(pos, "\"signed\" qualifier is illegal with non-integer type " Error(pos, "\"signed\" qualifier is illegal with non-integer type "
"\"%s\".", resolvedType->GetString().c_str()); "\"%s\".", resolvedType->GetString().c_str());
@@ -147,7 +147,7 @@ DeclSpecs::GetBaseType(SourcePos pos) const {
} }
retType = lApplyTypeQualifiers(typeQualifiers, retType, pos); retType = lApplyTypeQualifiers(typeQualifiers, retType, pos);
if (soaWidth > 0) { if (soaWidth > 0) {
const StructType *st = CastType<StructType>(retType); const StructType *st = CastType<StructType>(retType);
@@ -180,7 +180,7 @@ DeclSpecs::GetBaseType(SourcePos pos) const {
"currently leads to inefficient code to access " "currently leads to inefficient code to access "
"soa types.", soaWidth, g->target.vectorWidth); "soa types.", soaWidth, g->target.vectorWidth);
} }
return retType; return retType;
} }
@@ -215,8 +215,8 @@ DeclSpecs::Print() const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Declarator // Declarator
Declarator::Declarator(DeclaratorKind dk, SourcePos p) Declarator::Declarator(DeclaratorKind dk, SourcePos p)
: pos(p), kind(dk) { : pos(p), kind(dk) {
child = NULL; child = NULL;
typeQualifiers = 0; typeQualifiers = 0;
storageClass = SC_NONE; storageClass = SC_NONE;
@@ -238,7 +238,7 @@ Declarator::InitFromDeclSpecs(DeclSpecs *ds) {
storageClass = ds->storageClass; storageClass = ds->storageClass;
if (ds->declSpecList.size() > 0 && if (ds->declSpecList.size() > 0 &&
CastType<FunctionType>(type) == NULL) { CastType<FunctionType>(type) == NULL) {
Error(pos, "__declspec specifiers for non-function type \"%s\" are " Error(pos, "__declspec specifiers for non-function type \"%s\" are "
"not used.", type->GetString().c_str()); "not used.", type->GetString().c_str());
@@ -315,7 +315,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
Error(pos, "\"export\" qualifier illegal in variable declaration."); Error(pos, "\"export\" qualifier illegal in variable declaration.");
return; return;
} }
Variability variability(Variability::Unbound); Variability variability(Variability::Unbound);
if (hasUniformQual) if (hasUniformQual)
variability = Variability::Uniform; variability = Variability::Uniform;
@@ -396,7 +396,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
llvm::SmallVector<std::string, 8> argNames; llvm::SmallVector<std::string, 8> argNames;
llvm::SmallVector<Expr *, 8> argDefaults; llvm::SmallVector<Expr *, 8> argDefaults;
llvm::SmallVector<SourcePos, 8> argPos; llvm::SmallVector<SourcePos, 8> argPos;
// Loop over the function arguments and store the names, types, // Loop over the function arguments and store the names, types,
// default values (if any), and source file positions each one in // default values (if any), and source file positions each one in
// the corresponding vector. // the corresponding vector.
@@ -431,7 +431,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
if (d->declSpecs->storageClass != SC_NONE) if (d->declSpecs->storageClass != SC_NONE)
Error(decl->pos, "Storage class \"%s\" is illegal in " Error(decl->pos, "Storage class \"%s\" is illegal in "
"function parameter declaration for parameter \"%s\".", "function parameter declaration for parameter \"%s\".",
lGetStorageClassName(d->declSpecs->storageClass), lGetStorageClassName(d->declSpecs->storageClass),
decl->name.c_str()); decl->name.c_str());
if (Type::Equal(decl->type, AtomicType::Void)) { if (Type::Equal(decl->type, AtomicType::Void)) {
@@ -486,7 +486,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
init = dynamic_cast<NullPointerExpr *>(decl->initExpr); init = dynamic_cast<NullPointerExpr *>(decl->initExpr);
if (init == NULL) if (init == NULL)
Error(decl->initExpr->pos, "Default value for parameter " Error(decl->initExpr->pos, "Default value for parameter "
"\"%s\" must be a compile-time constant.", "\"%s\" must be a compile-time constant.",
decl->name.c_str()); decl->name.c_str());
} }
break; break;
@@ -507,14 +507,14 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
Error(pos, "Illegal to return function type from function."); Error(pos, "Illegal to return function type from function.");
return; return;
} }
returnType = returnType->ResolveUnboundVariability(Variability::Varying); returnType = returnType->ResolveUnboundVariability(Variability::Varying);
bool isExternC = ds && (ds->storageClass == SC_EXTERN_C); bool isExternC = ds && (ds->storageClass == SC_EXTERN_C);
bool isExported = ds && ((ds->typeQualifiers & TYPEQUAL_EXPORT) != 0); bool isExported = ds && ((ds->typeQualifiers & TYPEQUAL_EXPORT) != 0);
bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0); bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0);
bool isUnmasked = ds && ((ds->typeQualifiers & TYPEQUAL_UNMASKED) != 0); bool isUnmasked = ds && ((ds->typeQualifiers & TYPEQUAL_UNMASKED) != 0);
if (isExported && isTask) { if (isExported && isTask) {
Error(pos, "Function can't have both \"task\" and \"export\" " Error(pos, "Function can't have both \"task\" and \"export\" "
"qualifiers"); "qualifiers");
@@ -539,7 +539,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
return; return;
} }
const FunctionType *functionType = const FunctionType *functionType =
new FunctionType(returnType, args, argNames, argDefaults, new FunctionType(returnType, args, argNames, argDefaults,
argPos, isTask, isExported, isExternC, isUnmasked); argPos, isTask, isExported, isExternC, isUnmasked);
@@ -669,7 +669,7 @@ GetStructTypesNamesPositions(const std::vector<StructDeclaration *> &sd,
// disgusting // disgusting
DeclSpecs ds(type); DeclSpecs ds(type);
if (Type::Equal(type, AtomicType::Void) == false) { if (Type::Equal(type, AtomicType::Void) == false) {
if (type->IsUniformType()) if (type->IsUniformType())
ds.typeQualifiers |= TYPEQUAL_UNIFORM; ds.typeQualifiers |= TYPEQUAL_UNIFORM;
else if (type->IsVaryingType()) else if (type->IsVaryingType())
ds.typeQualifiers |= TYPEQUAL_VARYING; ds.typeQualifiers |= TYPEQUAL_VARYING;

8
decl.h
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file decl.h /** @file decl.h
@@ -48,7 +48,7 @@
qualifiers, and that it's basic type is 'int'. Then for each variable qualifiers, and that it's basic type is 'int'. Then for each variable
declaration, the Declaraiton class holds an instance of a Declarator, declaration, the Declaraiton class holds an instance of a Declarator,
which in turn records the per-variable information like the name, array which in turn records the per-variable information like the name, array
size (if any), initializer expression, etc. size (if any), initializer expression, etc.
*/ */
#ifndef ISPC_DECL_H #ifndef ISPC_DECL_H
@@ -124,7 +124,7 @@ enum DeclaratorKind {
DK_FUNCTION DK_FUNCTION
}; };
/** @brief Representation of the declaration of a single variable. /** @brief Representation of the declaration of a single variable.
In conjunction with an instance of the DeclSpecs, this gives us In conjunction with an instance of the DeclSpecs, this gives us
everything we need for a full variable declaration. everything we need for a full variable declaration.
@@ -162,7 +162,7 @@ public:
StorageClass storageClass; StorageClass storageClass;
/** For array declarators, this gives the declared size of the array. /** For array declarators, this gives the declared size of the array.
Unsized arrays have arraySize == 0. */ Unsized arrays have arraySize == 0. */
int arraySize; int arraySize;
/** Name associated with the declarator. */ /** Name associated with the declarator. */

708
expr.cpp

File diff suppressed because it is too large Load Diff

24
expr.h
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file expr.h /** @file expr.h
@@ -101,7 +101,7 @@ class UnaryExpr : public Expr {
public: public:
enum Op { enum Op {
PreInc, ///< Pre-increment PreInc, ///< Pre-increment
PreDec, ///< Pre-decrement PreDec, ///< Pre-decrement
PostInc, ///< Post-increment PostInc, ///< Post-increment
PostDec, ///< Post-decrement PostDec, ///< Post-decrement
Negate, ///< Negation Negate, ///< Negation
@@ -198,7 +198,7 @@ public:
}; };
/** @brief Selection expression, corresponding to "test ? a : b". /** @brief Selection expression, corresponding to "test ? a : b".
Returns the value of "a" or "b", depending on the value of "test". Returns the value of "a" or "b", depending on the value of "test".
*/ */
@@ -245,7 +245,7 @@ public:
*/ */
class FunctionCallExpr : public Expr { class FunctionCallExpr : public Expr {
public: public:
FunctionCallExpr(Expr *func, ExprList *args, SourcePos p, FunctionCallExpr(Expr *func, ExprList *args, SourcePos p,
bool isLaunch = false, Expr *launchCountExpr = NULL); bool isLaunch = false, Expr *launchCountExpr = NULL);
llvm::Value *GetValue(FunctionEmitContext *ctx) const; llvm::Value *GetValue(FunctionEmitContext *ctx) const;
@@ -266,7 +266,7 @@ public:
/** @brief Expression representing indexing into something with an integer /** @brief Expression representing indexing into something with an integer
offset. offset.
This is used for both array indexing and indexing into VectorTypes. This is used for both array indexing and indexing into VectorTypes.
*/ */
class IndexExpr : public Expr { class IndexExpr : public Expr {
public: public:
@@ -317,7 +317,7 @@ public:
std::string identifier; std::string identifier;
const SourcePos identifierPos; const SourcePos identifierPos;
MemberExpr(Expr *expr, const char *identifier, SourcePos pos, MemberExpr(Expr *expr, const char *identifier, SourcePos pos,
SourcePos identifierPos, bool derefLValue); SourcePos identifierPos, bool derefLValue);
/** Indicates whether the expression should be dereferenced before the /** Indicates whether the expression should be dereferenced before the
@@ -330,7 +330,7 @@ protected:
}; };
/** @brief Expression representing a compile-time constant value. /** @brief Expression representing a compile-time constant value.
This class can currently represent compile-time constants of anything This class can currently represent compile-time constants of anything
that is an AtomicType or an EnumType; for anything more complex, we that is an AtomicType or an EnumType; for anything more complex, we
@@ -640,7 +640,7 @@ private:
/** @brief Expression representing a function symbol in the program (generally /** @brief Expression representing a function symbol in the program (generally
used for a function call). used for a function call).
*/ */
class FunctionSymbolExpr : public Expr { class FunctionSymbolExpr : public Expr {
public: public:
FunctionSymbolExpr(const char *name, const std::vector<Symbol *> &candFuncs, FunctionSymbolExpr(const char *name, const std::vector<Symbol *> &candFuncs,
@@ -714,7 +714,7 @@ public:
class NullPointerExpr : public Expr { class NullPointerExpr : public Expr {
public: public:
NullPointerExpr(SourcePos p) : Expr(p) { } NullPointerExpr(SourcePos p) : Expr(p) { }
llvm::Value *GetValue(FunctionEmitContext *ctx) const; llvm::Value *GetValue(FunctionEmitContext *ctx) const;
const Type *GetType() const; const Type *GetType() const;
Expr *TypeCheck(); Expr *TypeCheck();
@@ -726,11 +726,11 @@ public:
/** An expression representing a "new" expression, used for dynamically /** An expression representing a "new" expression, used for dynamically
allocating memory. allocating memory.
*/ */
class NewExpr : public Expr { class NewExpr : public Expr {
public: public:
NewExpr(int typeQual, const Type *type, Expr *initializer, Expr *count, NewExpr(int typeQual, const Type *type, Expr *initializer, Expr *count,
SourcePos tqPos, SourcePos p); SourcePos tqPos, SourcePos p);
llvm::Value *GetValue(FunctionEmitContext *ctx) const; llvm::Value *GetValue(FunctionEmitContext *ctx) const;
@@ -742,7 +742,7 @@ public:
/** Type of object to allocate storage for. */ /** Type of object to allocate storage for. */
const Type *allocType; const Type *allocType;
/** Expression giving the number of elements to allocate, when the /** Expression giving the number of elements to allocate, when the
"new Foo[expr]" form is used. This may be NULL, in which case a "new Foo[expr]" form is used. This may be NULL, in which case a
single element of the given type will be allocated. */ single element of the given type will be allocated. */
Expr *countExpr; Expr *countExpr;

View File

@@ -28,11 +28,11 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file func.cpp /** @file func.cpp
@brief @brief
*/ */
#include "func.h" #include "func.h"
@@ -85,7 +85,7 @@ Function::Function(Symbol *s, Stmt *c) {
code = TypeCheck(code); code = TypeCheck(code);
if (code != NULL && g->debugPrint) { if (code != NULL && g->debugPrint) {
fprintf(stderr, "After typechecking function \"%s\":\n", fprintf(stderr, "After typechecking function \"%s\":\n",
sym->name.c_str()); sym->name.c_str());
code->Print(0); code->Print(0);
fprintf(stderr, "---------------------\n"); fprintf(stderr, "---------------------\n");
@@ -94,7 +94,7 @@ Function::Function(Symbol *s, Stmt *c) {
if (code != NULL) { if (code != NULL) {
code = Optimize(code); code = Optimize(code);
if (g->debugPrint) { if (g->debugPrint) {
fprintf(stderr, "After optimizing function \"%s\":\n", fprintf(stderr, "After optimizing function \"%s\":\n",
sym->name.c_str()); sym->name.c_str());
code->Print(0); code->Print(0);
fprintf(stderr, "---------------------\n"); fprintf(stderr, "---------------------\n");
@@ -160,7 +160,7 @@ Function::GetType() const {
'mem2reg' pass will in turn promote to SSA registers.. 'mem2reg' pass will in turn promote to SSA registers..
*/ */
static void static void
lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const
std::vector<Symbol *> &args, std::vector<Symbol *> &args,
FunctionEmitContext *ctx) { FunctionEmitContext *ctx) {
// We expect the argument structure to come in as a poitner to a // We expect the argument structure to come in as a poitner to a
@@ -169,7 +169,7 @@ lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const
Assert(llvm::isa<llvm::PointerType>(structArgType)); Assert(llvm::isa<llvm::PointerType>(structArgType));
const llvm::PointerType *pt = llvm::dyn_cast<const llvm::PointerType>(structArgType); const llvm::PointerType *pt = llvm::dyn_cast<const llvm::PointerType>(structArgType);
Assert(llvm::isa<llvm::StructType>(pt->getElementType())); Assert(llvm::isa<llvm::StructType>(pt->getElementType()));
const llvm::StructType *argStructType = const llvm::StructType *argStructType =
llvm::dyn_cast<const llvm::StructType>(pt->getElementType()); llvm::dyn_cast<const llvm::StructType>(pt->getElementType());
// Get the type of the argument we're copying in and its Symbol pointer // Get the type of the argument we're copying in and its Symbol pointer
@@ -199,8 +199,8 @@ lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const
involves wiring up the function parameter values to be available in the involves wiring up the function parameter values to be available in the
function body code. function body code.
*/ */
void void
Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function, Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
SourcePos firstStmtPos) { SourcePos firstStmtPos) {
// Connect the __mask builtin to the location in memory that stores its // Connect the __mask builtin to the location in memory that stores its
// value // value
@@ -259,7 +259,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
} }
else { else {
// Regular, non-task function // Regular, non-task function
llvm::Function::arg_iterator argIter = function->arg_begin(); llvm::Function::arg_iterator argIter = function->arg_begin();
for (unsigned int i = 0; i < args.size(); ++i, ++argIter) { for (unsigned int i = 0; i < args.size(); ++i, ++argIter) {
Symbol *sym = args[i]; Symbol *sym = args[i];
if (sym == NULL) if (sym == NULL)
@@ -301,14 +301,14 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
ctx->AddInstrumentationPoint("function entry"); ctx->AddInstrumentationPoint("function entry");
int costEstimate = EstimateCost(code); int costEstimate = EstimateCost(code);
Debug(code->pos, "Estimated cost for function \"%s\" = %d\n", Debug(code->pos, "Estimated cost for function \"%s\" = %d\n",
sym->name.c_str(), costEstimate); sym->name.c_str(), costEstimate);
// If the body of the function is non-trivial, then we wrap the // If the body of the function is non-trivial, then we wrap the
// entire thing inside code that tests to see if the mask is all // entire thing inside code that tests to see if the mask is all
// on, all off, or mixed. If this is a simple function, then this // on, all off, or mixed. If this is a simple function, then this
// isn't worth the code bloat / overhead. // isn't worth the code bloat / overhead.
bool checkMask = (type->isTask == true) || bool checkMask = (type->isTask == true) ||
( (
#if defined(LLVM_3_1) #if defined(LLVM_3_1)
(function->hasFnAttr(llvm::Attribute::AlwaysInline) == false) (function->hasFnAttr(llvm::Attribute::AlwaysInline) == false)
@@ -322,7 +322,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
checkMask &= (type->isUnmasked == false); checkMask &= (type->isUnmasked == false);
checkMask &= (g->target.maskingIsFree == false); checkMask &= (g->target.maskingIsFree == false);
checkMask &= (g->opt.disableCoherentControlFlow == false); checkMask &= (g->opt.disableCoherentControlFlow == false);
if (checkMask) { if (checkMask) {
llvm::Value *mask = ctx->GetFunctionMask(); llvm::Value *mask = ctx->GetFunctionMask();
llvm::Value *allOn = ctx->All(mask); llvm::Value *allOn = ctx->All(mask);
@@ -409,7 +409,7 @@ Function::GenerateIR() {
// But if that function has a definition, we don't want to redefine it. // But if that function has a definition, we don't want to redefine it.
if (function->empty() == false) { if (function->empty() == false) {
Error(sym->pos, "Ignoring redefinition of function \"%s\".", Error(sym->pos, "Ignoring redefinition of function \"%s\".",
sym->name.c_str()); sym->name.c_str());
return; return;
} }
@@ -426,7 +426,7 @@ Function::GenerateIR() {
firstStmtPos = code->pos; firstStmtPos = code->pos;
} }
// And we can now go ahead and emit the code // And we can now go ahead and emit the code
{ {
FunctionEmitContext ec(this, sym, function, firstStmtPos); FunctionEmitContext ec(this, sym, function, firstStmtPos);
emitCode(&ec, function, firstStmtPos); emitCode(&ec, function, firstStmtPos);
@@ -451,7 +451,7 @@ Function::GenerateIR() {
std::string functionName = sym->name; std::string functionName = sym->name;
if (g->mangleFunctionsWithTarget) if (g->mangleFunctionsWithTarget)
functionName += std::string("_") + g->target.GetISAString(); functionName += std::string("_") + g->target.GetISAString();
llvm::Function *appFunction = llvm::Function *appFunction =
llvm::Function::Create(ftype, linkage, functionName.c_str(), m->module); llvm::Function::Create(ftype, linkage, functionName.c_str(), m->module);
#if defined(LLVM_3_1) #if defined(LLVM_3_1)
appFunction->setDoesNotThrow(true); appFunction->setDoesNotThrow(true);
@@ -470,7 +470,7 @@ Function::GenerateIR() {
emitCode(&ec, appFunction, firstStmtPos); emitCode(&ec, appFunction, firstStmtPos);
if (m->errorCount == 0) { if (m->errorCount == 0) {
sym->exportedFunction = appFunction; sym->exportedFunction = appFunction;
if (llvm::verifyFunction(*appFunction, if (llvm::verifyFunction(*appFunction,
llvm::ReturnStatusAction) == true) { llvm::ReturnStatusAction) == true) {
if (g->debugPrint) if (g->debugPrint)
appFunction->dump(); appFunction->dump();

4
func.h
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file func.h /** @file func.h
@@ -52,7 +52,7 @@ public:
void GenerateIR(); void GenerateIR();
private: private:
void emitCode(FunctionEmitContext *ctx, llvm::Function *function, void emitCode(FunctionEmitContext *ctx, llvm::Function *function,
SourcePos firstStmtPos); SourcePos firstStmtPos);
Symbol *sym; Symbol *sym;

View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file ispc.cpp /** @file ispc.cpp
@@ -136,7 +136,7 @@ lGetSystemISA() {
} }
static const char *supportedCPUs[] = { static const char *supportedCPUs[] = {
"atom", "penryn", "core2", "corei7", "corei7-avx" "atom", "penryn", "core2", "corei7", "corei7-avx"
#if defined(LLVM_3_2) || defined(LLVM_3_3) #if defined(LLVM_3_2) || defined(LLVM_3_3)
, "core-avx-i", "core-avx2" , "core-avx-i", "core-avx2"
@@ -187,7 +187,7 @@ Target::GetTarget(const char *arch, const char *cpu, const char *isa,
} }
else { else {
bool foundCPU = false; bool foundCPU = false;
for (int i = 0; i < int(sizeof(supportedCPUs) / sizeof(supportedCPUs[0])); for (int i = 0; i < int(sizeof(supportedCPUs) / sizeof(supportedCPUs[0]));
++i) { ++i) {
if (!strcmp(cpu, supportedCPUs[i])) { if (!strcmp(cpu, supportedCPUs[i])) {
foundCPU = true; foundCPU = true;
@@ -405,7 +405,7 @@ Target::GetTarget(const char *arch, const char *cpu, const char *isa,
#endif #endif
} }
else { else {
fprintf(stderr, "Target ISA \"%s\" is unknown. Choices are: %s\n", fprintf(stderr, "Target ISA \"%s\" is unknown. Choices are: %s\n",
isa, SupportedTargetISAs()); isa, SupportedTargetISAs());
error = true; error = true;
} }
@@ -494,7 +494,7 @@ llvm::TargetMachine *
Target::GetTargetMachine() const { Target::GetTargetMachine() const {
std::string triple = GetTripleString(); std::string triple = GetTripleString();
llvm::Reloc::Model relocModel = generatePIC ? llvm::Reloc::PIC_ : llvm::Reloc::Model relocModel = generatePIC ? llvm::Reloc::PIC_ :
llvm::Reloc::Default; llvm::Reloc::Default;
std::string featuresString = attributes; std::string featuresString = attributes;
llvm::TargetOptions options; llvm::TargetOptions options;
@@ -502,7 +502,7 @@ Target::GetTargetMachine() const {
if (g->opt.disableFMA == false) if (g->opt.disableFMA == false)
options.AllowFPOpFusion = llvm::FPOpFusion::Fast; options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
#endif // !LLVM_3_1 #endif // !LLVM_3_1
llvm::TargetMachine *targetMachine = llvm::TargetMachine *targetMachine =
target->createTargetMachine(triple, cpu, featuresString, options, target->createTargetMachine(triple, cpu, featuresString, options,
relocModel); relocModel);
Assert(targetMachine != NULL); Assert(targetMachine != NULL);
@@ -544,12 +544,12 @@ lGenericTypeLayoutIndeterminate(llvm::Type *type) {
type == LLVMTypes::Int1VectorType) type == LLVMTypes::Int1VectorType)
return true; return true;
llvm::ArrayType *at = llvm::ArrayType *at =
llvm::dyn_cast<llvm::ArrayType>(type); llvm::dyn_cast<llvm::ArrayType>(type);
if (at != NULL) if (at != NULL)
return lGenericTypeLayoutIndeterminate(at->getElementType()); return lGenericTypeLayoutIndeterminate(at->getElementType());
llvm::PointerType *pt = llvm::PointerType *pt =
llvm::dyn_cast<llvm::PointerType>(type); llvm::dyn_cast<llvm::PointerType>(type);
if (pt != NULL) if (pt != NULL)
return false; return false;
@@ -569,7 +569,7 @@ lGenericTypeLayoutIndeterminate(llvm::Type *type) {
llvm::Value * llvm::Value *
Target::SizeOf(llvm::Type *type, Target::SizeOf(llvm::Type *type,
llvm::BasicBlock *insertAtEnd) { llvm::BasicBlock *insertAtEnd) {
if (isa == Target::GENERIC && if (isa == Target::GENERIC &&
lGenericTypeLayoutIndeterminate(type)) { lGenericTypeLayoutIndeterminate(type)) {
@@ -577,15 +577,15 @@ Target::SizeOf(llvm::Type *type,
llvm::PointerType *ptrType = llvm::PointerType::get(type, 0); llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType); llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
llvm::ArrayRef<llvm::Value *> arrayRef(&index[0], &index[1]); llvm::ArrayRef<llvm::Value *> arrayRef(&index[0], &index[1]);
llvm::Instruction *gep = llvm::Instruction *gep =
llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "sizeof_gep", llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "sizeof_gep",
insertAtEnd); insertAtEnd);
if (is32Bit || g->opt.force32BitAddressing) if (is32Bit || g->opt.force32BitAddressing)
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type, return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
"sizeof_int", insertAtEnd); "sizeof_int", insertAtEnd);
else else
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type, return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
"sizeof_int", insertAtEnd); "sizeof_int", insertAtEnd);
} }
@@ -611,25 +611,25 @@ Target::SizeOf(llvm::Type *type,
llvm::Value * llvm::Value *
Target::StructOffset(llvm::Type *type, int element, Target::StructOffset(llvm::Type *type, int element,
llvm::BasicBlock *insertAtEnd) { llvm::BasicBlock *insertAtEnd) {
if (isa == Target::GENERIC && if (isa == Target::GENERIC &&
lGenericTypeLayoutIndeterminate(type) == true) { lGenericTypeLayoutIndeterminate(type) == true) {
llvm::Value *indices[2] = { LLVMInt32(0), LLVMInt32(element) }; llvm::Value *indices[2] = { LLVMInt32(0), LLVMInt32(element) };
llvm::PointerType *ptrType = llvm::PointerType::get(type, 0); llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType); llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
llvm::ArrayRef<llvm::Value *> arrayRef(&indices[0], &indices[2]); llvm::ArrayRef<llvm::Value *> arrayRef(&indices[0], &indices[2]);
llvm::Instruction *gep = llvm::Instruction *gep =
llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "offset_gep", llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "offset_gep",
insertAtEnd); insertAtEnd);
if (is32Bit || g->opt.force32BitAddressing) if (is32Bit || g->opt.force32BitAddressing)
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type, return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
"offset_int", insertAtEnd); "offset_int", insertAtEnd);
else else
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type, return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
"offset_int", insertAtEnd); "offset_int", insertAtEnd);
} }
llvm::StructType *structType = llvm::StructType *structType =
llvm::dyn_cast<llvm::StructType>(type); llvm::dyn_cast<llvm::StructType>(type);
if (structType == NULL || structType->isSized() == false) { if (structType == NULL || structType->isSized() == false) {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
@@ -699,7 +699,7 @@ Globals::Globals() {
enableFuzzTest = false; enableFuzzTest = false;
fuzzTestSeed = -1; fuzzTestSeed = -1;
mangleFunctionsWithTarget = false; mangleFunctionsWithTarget = false;
ctx = new llvm::LLVMContext; ctx = new llvm::LLVMContext;
#ifdef ISPC_IS_WINDOWS #ifdef ISPC_IS_WINDOWS
@@ -739,15 +739,15 @@ SourcePos::GetDIFile() const {
void void
SourcePos::Print() const { SourcePos::Print() const {
printf(" @ [%s:%d.%d - %d.%d] ", name, first_line, first_column, printf(" @ [%s:%d.%d - %d.%d] ", name, first_line, first_column,
last_line, last_column); last_line, last_column);
} }
bool bool
SourcePos::operator==(const SourcePos &p2) const { SourcePos::operator==(const SourcePos &p2) const {
return (!strcmp(name, p2.name) && return (!strcmp(name, p2.name) &&
first_line == p2.first_line && first_line == p2.first_line &&
first_column == p2.first_column && first_column == p2.first_column &&
last_line == p2.last_line && last_line == p2.last_line &&

18
ispc.h
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file ispc.h /** @file ispc.h
@@ -158,7 +158,7 @@ extern void DoAssertPos(SourcePos pos, const char *file, int line, const char *e
((void)((expr) ? 0 : ((void)DoAssertPos (pos, __FILE__, __LINE__, #expr), 0))) ((void)((expr) ? 0 : ((void)DoAssertPos (pos, __FILE__, __LINE__, #expr), 0)))
/** @brief Structure that defines a compilation target /** @brief Structure that defines a compilation target
This structure defines a compilation target for the ispc compiler. This structure defines a compilation target for the ispc compiler.
*/ */
@@ -188,7 +188,7 @@ struct Target {
/** Returns the LLVM TargetMachine object corresponding to this /** Returns the LLVM TargetMachine object corresponding to this
target. */ target. */
llvm::TargetMachine *GetTargetMachine() const; llvm::TargetMachine *GetTargetMachine() const;
/** Returns a string like "avx" encoding the target. */ /** Returns a string like "avx" encoding the target. */
const char *GetISAString() const; const char *GetISAString() const;
@@ -281,11 +281,11 @@ struct Target {
/** @brief Structure that collects optimization options /** @brief Structure that collects optimization options
This structure collects all of the options related to optimization of This structure collects all of the options related to optimization of
generated code. generated code.
*/ */
struct Opt { struct Opt {
Opt(); Opt();
/** Optimization level. Currently, the only valid values are 0, /** Optimization level. Currently, the only valid values are 0,
indicating essentially no optimization, and 1, indicating as much indicating essentially no optimization, and 1, indicating as much
optimization as possible. */ optimization as possible. */
@@ -308,7 +308,7 @@ struct Opt {
/** Indicates if addressing math will be done with 32-bit math, even on /** Indicates if addressing math will be done with 32-bit math, even on
64-bit systems. (This is generally noticably more efficient, 64-bit systems. (This is generally noticably more efficient,
though at the cost of addressing >2GB). though at the cost of addressing >2GB).
*/ */
bool force32BitAddressing; bool force32BitAddressing;
/** Indicates whether Assert() statements should be ignored (for /** Indicates whether Assert() statements should be ignored (for
@@ -387,7 +387,7 @@ struct Opt {
bool disableCoalescing; bool disableCoalescing;
}; };
/** @brief This structure collects together a number of global variables. /** @brief This structure collects together a number of global variables.
This structure collects a number of global variables that mostly This structure collects a number of global variables that mostly
represent parameter settings for this compilation run. In particular, represent parameter settings for this compilation run. In particular,
@@ -445,12 +445,12 @@ struct Globals {
externally-defined program instrumentation function. (See the externally-defined program instrumentation function. (See the
"Instrumenting your ispc programs" section in the user's "Instrumenting your ispc programs" section in the user's
manual.) */ manual.) */
bool emitInstrumentation; bool emitInstrumentation;
/** Indicates whether ispc should generate debugging symbols for the /** Indicates whether ispc should generate debugging symbols for the
program in its output. */ program in its output. */
bool generateDebuggingSymbols; bool generateDebuggingSymbols;
/** If true, function names are mangled by appending the target ISA and /** If true, function names are mangled by appending the target ISA and
vector width to them. */ vector width to them. */
bool mangleFunctionsWithTarget; bool mangleFunctionsWithTarget;

48
lex.ll
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
%{ %{
@@ -62,7 +62,7 @@ inline int isatty(int) { return 0; }
#include <unistd.h> #include <unistd.h>
#endif // ISPC_IS_WINDOWS #endif // ISPC_IS_WINDOWS
static int allTokens[] = { static int allTokens[] = {
TOKEN_ASSERT, TOKEN_BOOL, TOKEN_BREAK, TOKEN_CASE, TOKEN_ASSERT, TOKEN_BOOL, TOKEN_BREAK, TOKEN_CASE,
TOKEN_CDO, TOKEN_CFOR, TOKEN_CIF, TOKEN_CWHILE, TOKEN_CDO, TOKEN_CFOR, TOKEN_CIF, TOKEN_CWHILE,
TOKEN_CONST, TOKEN_CONTINUE, TOKEN_DEFAULT, TOKEN_DO, TOKEN_CONST, TOKEN_CONTINUE, TOKEN_DEFAULT, TOKEN_DO,
@@ -74,11 +74,11 @@ static int allTokens[] = {
TOKEN_NEW, TOKEN_NULL, TOKEN_PRINT, TOKEN_RETURN, TOKEN_SOA, TOKEN_SIGNED, TOKEN_NEW, TOKEN_NULL, TOKEN_PRINT, TOKEN_RETURN, TOKEN_SOA, TOKEN_SIGNED,
TOKEN_SIZEOF, TOKEN_STATIC, TOKEN_STRUCT, TOKEN_SWITCH, TOKEN_SYNC, TOKEN_SIZEOF, TOKEN_STATIC, TOKEN_STRUCT, TOKEN_SWITCH, TOKEN_SYNC,
TOKEN_TASK, TOKEN_TRUE, TOKEN_TYPEDEF, TOKEN_UNIFORM, TOKEN_UNMASKED, TOKEN_TASK, TOKEN_TRUE, TOKEN_TYPEDEF, TOKEN_UNIFORM, TOKEN_UNMASKED,
TOKEN_UNSIGNED, TOKEN_VARYING, TOKEN_VOID, TOKEN_WHILE, TOKEN_UNSIGNED, TOKEN_VARYING, TOKEN_VOID, TOKEN_WHILE,
TOKEN_STRING_C_LITERAL, TOKEN_DOTDOTDOT, TOKEN_STRING_C_LITERAL, TOKEN_DOTDOTDOT,
TOKEN_FLOAT_CONSTANT, TOKEN_FLOAT_CONSTANT,
TOKEN_INT32_CONSTANT, TOKEN_UINT32_CONSTANT, TOKEN_INT32_CONSTANT, TOKEN_UINT32_CONSTANT,
TOKEN_INT64_CONSTANT, TOKEN_UINT64_CONSTANT, TOKEN_INT64_CONSTANT, TOKEN_UINT64_CONSTANT,
TOKEN_INC_OP, TOKEN_DEC_OP, TOKEN_LEFT_OP, TOKEN_RIGHT_OP, TOKEN_LE_OP, TOKEN_INC_OP, TOKEN_DEC_OP, TOKEN_LEFT_OP, TOKEN_RIGHT_OP, TOKEN_LE_OP,
TOKEN_GE_OP, TOKEN_EQ_OP, TOKEN_NE_OP, TOKEN_AND_OP, TOKEN_OR_OP, TOKEN_GE_OP, TOKEN_EQ_OP, TOKEN_NE_OP, TOKEN_AND_OP, TOKEN_OR_OP,
TOKEN_MUL_ASSIGN, TOKEN_DIV_ASSIGN, TOKEN_MOD_ASSIGN, TOKEN_ADD_ASSIGN, TOKEN_MUL_ASSIGN, TOKEN_DIV_ASSIGN, TOKEN_MOD_ASSIGN, TOKEN_ADD_ASSIGN,
@@ -406,7 +406,7 @@ while { RT; return TOKEN_WHILE; }
L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERAL; } L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERAL; }
{IDENT} { {IDENT} {
RT; RT;
/* We have an identifier--is it a type name or an identifier? /* We have an identifier--is it a type name or an identifier?
The symbol table will straighten us out... */ The symbol table will straighten us out... */
@@ -414,10 +414,10 @@ L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERA
if (m->symbolTable->LookupType(yytext) != NULL) if (m->symbolTable->LookupType(yytext) != NULL)
return TOKEN_TYPE_NAME; return TOKEN_TYPE_NAME;
else else
return TOKEN_IDENTIFIER; return TOKEN_IDENTIFIER;
} }
{INT_NUMBER} { {INT_NUMBER} {
RT; RT;
return lParseInteger(false); return lParseInteger(false);
} }
@@ -428,16 +428,16 @@ L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERA
} }
{FLOAT_NUMBER} { {FLOAT_NUMBER} {
RT; RT;
yylval.floatVal = (float)atof(yytext); yylval.floatVal = (float)atof(yytext);
return TOKEN_FLOAT_CONSTANT; return TOKEN_FLOAT_CONSTANT;
} }
{HEX_FLOAT_NUMBER} { {HEX_FLOAT_NUMBER} {
RT; RT;
yylval.floatVal = (float)lParseHexFloat(yytext); yylval.floatVal = (float)lParseHexFloat(yytext);
return TOKEN_FLOAT_CONSTANT; return TOKEN_FLOAT_CONSTANT;
} }
"++" { RT; return TOKEN_INC_OP; } "++" { RT; return TOKEN_INC_OP; }
@@ -489,17 +489,17 @@ L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERA
{WHITESPACE} { } {WHITESPACE} { }
\n { \n {
yylloc.last_line++; yylloc.last_line++;
yylloc.last_column = 1; yylloc.last_column = 1;
} }
#(line)?[ ][0-9]+[ ]\"(\\.|[^\\"])*\"[^\n]* { #(line)?[ ][0-9]+[ ]\"(\\.|[^\\"])*\"[^\n]* {
lHandleCppHash(&yylloc); lHandleCppHash(&yylloc);
} }
. { . {
Error(yylloc, "Illegal character: %c (0x%x)", yytext[0], int(yytext[0])); Error(yylloc, "Illegal character: %c (0x%x)", yytext[0], int(yytext[0]));
YY_USER_ACTION YY_USER_ACTION
} }
%% %%
@@ -558,7 +558,7 @@ lParseInteger(bool dotdotdot) {
else if (*endPtr == 'M') else if (*endPtr == 'M')
mega = true; mega = true;
else if (*endPtr == 'G') else if (*endPtr == 'G')
giga = true; giga = true;
else if (*endPtr == 'l' || *endPtr == 'L') else if (*endPtr == 'l' || *endPtr == 'L')
ls++; ls++;
else if (*endPtr == 'u' || *endPtr == 'U') else if (*endPtr == 'u' || *endPtr == 'U')
@@ -598,7 +598,7 @@ lParseInteger(bool dotdotdot) {
return TOKEN_UINT64_CONSTANT; return TOKEN_UINT64_CONSTANT;
} }
else { else {
// No u or l suffix // No u or l suffix
// First, see if we can fit this into a 32-bit integer... // First, see if we can fit this into a 32-bit integer...
if (yylval.intVal <= 0x7fffffffULL) if (yylval.intVal <= 0x7fffffffULL)
return TOKEN_INT32_CONSTANT; return TOKEN_INT32_CONSTANT;
@@ -613,7 +613,7 @@ lParseInteger(bool dotdotdot) {
} }
/** Handle a C-style comment in the source. /** Handle a C-style comment in the source.
*/ */
static void static void
lCComment(SourcePos *pos) { lCComment(SourcePos *pos) {
@@ -750,7 +750,7 @@ lStringConst(YYSTYPE *yylval, SourcePos *pos)
char cval = '\0'; char cval = '\0';
p = lEscapeChar(p, &cval, pos); p = lEscapeChar(p, &cval, pos);
str.push_back(cval); str.push_back(cval);
} }
yylval->stringVal = new std::string(str); yylval->stringVal = new std::string(str);
} }
@@ -758,7 +758,7 @@ lStringConst(YYSTYPE *yylval, SourcePos *pos)
/** Compute the value 2^n, where the exponent is given as an integer. /** Compute the value 2^n, where the exponent is given as an integer.
There are more efficient ways to do this, for example by just slamming There are more efficient ways to do this, for example by just slamming
the bits into the appropriate bits of the double, but let's just do the the bits into the appropriate bits of the double, but let's just do the
obvious thing. obvious thing.
*/ */
static double static double
ipow2(int exponent) { ipow2(int exponent) {
@@ -777,7 +777,7 @@ ipow2(int exponent) {
/** Parse a hexadecimal-formatted floating-point number (C99 hex float /** Parse a hexadecimal-formatted floating-point number (C99 hex float
constant-style). constant-style).
*/ */
static double static double
lParseHexFloat(const char *ptr) { lParseHexFloat(const char *ptr) {

View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file llvmutil.cpp /** @file llvmutil.cpp
@@ -124,19 +124,19 @@ InitLLVMUtil(llvm::LLVMContext *ctx, Target target) {
llvm::VectorType::get(llvm::Type::getInt32Ty(*ctx), target.vectorWidth); llvm::VectorType::get(llvm::Type::getInt32Ty(*ctx), target.vectorWidth);
} }
LLVMTypes::Int1VectorType = LLVMTypes::Int1VectorType =
llvm::VectorType::get(llvm::Type::getInt1Ty(*ctx), target.vectorWidth); llvm::VectorType::get(llvm::Type::getInt1Ty(*ctx), target.vectorWidth);
LLVMTypes::Int8VectorType = LLVMTypes::Int8VectorType =
llvm::VectorType::get(LLVMTypes::Int8Type, target.vectorWidth); llvm::VectorType::get(LLVMTypes::Int8Type, target.vectorWidth);
LLVMTypes::Int16VectorType = LLVMTypes::Int16VectorType =
llvm::VectorType::get(LLVMTypes::Int16Type, target.vectorWidth); llvm::VectorType::get(LLVMTypes::Int16Type, target.vectorWidth);
LLVMTypes::Int32VectorType = LLVMTypes::Int32VectorType =
llvm::VectorType::get(LLVMTypes::Int32Type, target.vectorWidth); llvm::VectorType::get(LLVMTypes::Int32Type, target.vectorWidth);
LLVMTypes::Int64VectorType = LLVMTypes::Int64VectorType =
llvm::VectorType::get(LLVMTypes::Int64Type, target.vectorWidth); llvm::VectorType::get(LLVMTypes::Int64Type, target.vectorWidth);
LLVMTypes::FloatVectorType = LLVMTypes::FloatVectorType =
llvm::VectorType::get(LLVMTypes::FloatType, target.vectorWidth); llvm::VectorType::get(LLVMTypes::FloatType, target.vectorWidth);
LLVMTypes::DoubleVectorType = LLVMTypes::DoubleVectorType =
llvm::VectorType::get(LLVMTypes::DoubleType, target.vectorWidth); llvm::VectorType::get(LLVMTypes::DoubleType, target.vectorWidth);
LLVMTypes::Int8VectorPointerType = llvm::PointerType::get(LLVMTypes::Int8VectorType, 0); LLVMTypes::Int8VectorPointerType = llvm::PointerType::get(LLVMTypes::Int8VectorType, 0);
@@ -441,11 +441,11 @@ LLVMUInt64Vector(const uint64_t *ivec) {
llvm::Constant * llvm::Constant *
LLVMBoolVector(bool b) { LLVMBoolVector(bool b) {
llvm::Constant *v; llvm::Constant *v;
if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType) if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
v = llvm::ConstantInt::get(LLVMTypes::Int32Type, b ? 0xffffffff : 0, v = llvm::ConstantInt::get(LLVMTypes::Int32Type, b ? 0xffffffff : 0,
false /*unsigned*/); false /*unsigned*/);
else { else {
Assert(LLVMTypes::BoolVectorType->getElementType() == Assert(LLVMTypes::BoolVectorType->getElementType() ==
llvm::Type::getInt1Ty(*g->ctx)); llvm::Type::getInt1Ty(*g->ctx));
v = b ? LLVMTrue : LLVMFalse; v = b ? LLVMTrue : LLVMFalse;
} }
@@ -462,11 +462,11 @@ LLVMBoolVector(const bool *bvec) {
std::vector<llvm::Constant *> vals; std::vector<llvm::Constant *> vals;
for (int i = 0; i < g->target.vectorWidth; ++i) { for (int i = 0; i < g->target.vectorWidth; ++i) {
llvm::Constant *v; llvm::Constant *v;
if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType) if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
v = llvm::ConstantInt::get(LLVMTypes::Int32Type, bvec[i] ? 0xffffffff : 0, v = llvm::ConstantInt::get(LLVMTypes::Int32Type, bvec[i] ? 0xffffffff : 0,
false /*unsigned*/); false /*unsigned*/);
else { else {
Assert(LLVMTypes::BoolVectorType->getElementType() == Assert(LLVMTypes::BoolVectorType->getElementType() ==
llvm::Type::getInt1Ty(*g->ctx)); llvm::Type::getInt1Ty(*g->ctx));
v = bvec[i] ? LLVMTrue : LLVMFalse; v = bvec[i] ? LLVMTrue : LLVMFalse;
} }
@@ -519,7 +519,7 @@ LLVMUIntAsType(uint64_t val, llvm::Type *type) {
vectors definitely are equal. vectors definitely are equal.
*/ */
static bool static bool
lValuesAreEqual(llvm::Value *v0, llvm::Value *v1, lValuesAreEqual(llvm::Value *v0, llvm::Value *v1,
std::vector<llvm::PHINode *> &seenPhi0, std::vector<llvm::PHINode *> &seenPhi0,
std::vector<llvm::PHINode *> &seenPhi1) { std::vector<llvm::PHINode *> &seenPhi1) {
// Thanks to the fact that LLVM hashes and returns the same pointer for // Thanks to the fact that LLVM hashes and returns the same pointer for
@@ -571,7 +571,7 @@ lValuesAreEqual(llvm::Value *v0, llvm::Value *v1,
// FIXME: should it be ok if the incoming blocks are different, // FIXME: should it be ok if the incoming blocks are different,
// where we just return faliure in this case? // where we just return faliure in this case?
Assert(phi0->getIncomingBlock(i) == phi1->getIncomingBlock(i)); Assert(phi0->getIncomingBlock(i) == phi1->getIncomingBlock(i));
if (!lValuesAreEqual(phi0->getIncomingValue(i), if (!lValuesAreEqual(phi0->getIncomingValue(i),
phi1->getIncomingValue(i), seenPhi0, seenPhi1)) { phi1->getIncomingValue(i), seenPhi0, seenPhi1)) {
anyFailure = true; anyFailure = true;
break; break;
@@ -611,7 +611,7 @@ LLVMFlattenInsertChain(llvm::InsertElementInst *ie, int vectorWidth,
Assert(iOffset >= 0 && iOffset < vectorWidth); Assert(iOffset >= 0 && iOffset < vectorWidth);
Assert(elements[iOffset] == NULL); Assert(elements[iOffset] == NULL);
// Get the scalar value from this insert // Get the scalar value from this insert
elements[iOffset] = ie->getOperand(1); elements[iOffset] = ie->getOperand(1);
// Do we have another insert? // Do we have another insert?
@@ -623,7 +623,7 @@ LLVMFlattenInsertChain(llvm::InsertElementInst *ie, int vectorWidth,
// Get the value out of a constant vector if that's what we // Get the value out of a constant vector if that's what we
// have // have
llvm::ConstantVector *cv = llvm::ConstantVector *cv =
llvm::dyn_cast<llvm::ConstantVector>(insertBase); llvm::dyn_cast<llvm::ConstantVector>(insertBase);
// FIXME: this assert is a little questionable; we probably // FIXME: this assert is a little questionable; we probably
@@ -717,7 +717,7 @@ lIsExactMultiple(llvm::Value *val, int baseValue, int vectorLength,
// we're good. // we're good.
for (unsigned int i = 0; i < numIncoming; ++i) { for (unsigned int i = 0; i < numIncoming; ++i) {
llvm::Value *incoming = phi->getIncomingValue(i); llvm::Value *incoming = phi->getIncomingValue(i);
bool mult = lIsExactMultiple(incoming, baseValue, vectorLength, bool mult = lIsExactMultiple(incoming, baseValue, vectorLength,
seenPhis); seenPhis);
if (mult == false) { if (mult == false) {
seenPhis.pop_back(); seenPhis.pop_back();
@@ -748,9 +748,9 @@ lIsExactMultiple(llvm::Value *val, int baseValue, int vectorLength,
static int static int
lRoundUpPow2(int v) { lRoundUpPow2(int v) {
v--; v--;
v |= v >> 1; v |= v >> 1;
v |= v >> 2; v |= v >> 2;
v |= v >> 4; v |= v >> 4;
v |= v >> 8; v |= v >> 8;
v |= v >> 16; v |= v >> 16;
return v+1; return v+1;
@@ -804,7 +804,7 @@ lAllDivBaseEqual(llvm::Value *val, int64_t baseValue, int vectorLength,
for (unsigned int i = 0; i < numIncoming; ++i) { for (unsigned int i = 0; i < numIncoming; ++i) {
llvm::Value *incoming = phi->getIncomingValue(i); llvm::Value *incoming = phi->getIncomingValue(i);
bool ca = canAdd; bool ca = canAdd;
bool mult = lAllDivBaseEqual(incoming, baseValue, vectorLength, bool mult = lAllDivBaseEqual(incoming, baseValue, vectorLength,
seenPhis, ca); seenPhis, ca);
if (mult == false) { if (mult == false) {
seenPhis.pop_back(); seenPhis.pop_back();
@@ -816,7 +816,7 @@ lAllDivBaseEqual(llvm::Value *val, int64_t baseValue, int vectorLength,
} }
llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(val); llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(val);
if (bop != NULL && bop->getOpcode() == llvm::Instruction::Add && if (bop != NULL && bop->getOpcode() == llvm::Instruction::Add &&
canAdd == true) { canAdd == true) {
llvm::Value *op0 = bop->getOperand(0); llvm::Value *op0 = bop->getOperand(0);
llvm::Value *op1 = bop->getOperand(1); llvm::Value *op1 = bop->getOperand(1);
@@ -942,9 +942,9 @@ lVectorValuesAllEqual(llvm::Value *v, int vectorLength,
llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(v); llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(v);
if (bop != NULL) { if (bop != NULL) {
// Easy case: both operands are all equal -> return true // Easy case: both operands are all equal -> return true
if (lVectorValuesAllEqual(bop->getOperand(0), vectorLength, if (lVectorValuesAllEqual(bop->getOperand(0), vectorLength,
seenPhis) && seenPhis) &&
lVectorValuesAllEqual(bop->getOperand(1), vectorLength, lVectorValuesAllEqual(bop->getOperand(1), vectorLength,
seenPhis)) seenPhis))
return true; return true;
@@ -952,7 +952,7 @@ lVectorValuesAllEqual(llvm::Value *v, int vectorLength,
// high (surviving) bits of the values are equal. // high (surviving) bits of the values are equal.
if (bop->getOpcode() == llvm::Instruction::AShr || if (bop->getOpcode() == llvm::Instruction::AShr ||
bop->getOpcode() == llvm::Instruction::LShr) bop->getOpcode() == llvm::Instruction::LShr)
return lVectorShiftRightAllEqual(bop->getOperand(0), return lVectorShiftRightAllEqual(bop->getOperand(0),
bop->getOperand(1), vectorLength); bop->getOperand(1), vectorLength);
return false; return false;
@@ -960,7 +960,7 @@ lVectorValuesAllEqual(llvm::Value *v, int vectorLength,
llvm::CastInst *cast = llvm::dyn_cast<llvm::CastInst>(v); llvm::CastInst *cast = llvm::dyn_cast<llvm::CastInst>(v);
if (cast != NULL) if (cast != NULL)
return lVectorValuesAllEqual(cast->getOperand(0), vectorLength, return lVectorValuesAllEqual(cast->getOperand(0), vectorLength,
seenPhis); seenPhis);
llvm::InsertElementInst *ie = llvm::dyn_cast<llvm::InsertElementInst>(v); llvm::InsertElementInst *ie = llvm::dyn_cast<llvm::InsertElementInst>(v);
@@ -985,7 +985,7 @@ lVectorValuesAllEqual(llvm::Value *v, int vectorLength,
std::vector<llvm::PHINode *> seenPhi0; std::vector<llvm::PHINode *> seenPhi0;
std::vector<llvm::PHINode *> seenPhi1; std::vector<llvm::PHINode *> seenPhi1;
if (lValuesAreEqual(elements[lastNonNull], elements[i], seenPhi0, if (lValuesAreEqual(elements[lastNonNull], elements[i], seenPhi0,
seenPhi1) == false) seenPhi1) == false)
return false; return false;
lastNonNull = i; lastNonNull = i;
@@ -1087,8 +1087,8 @@ lVectorIsLinear(llvm::Value *v, int vectorLength, int stride,
elements. elements.
*/ */
static bool static bool
lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv, lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
int vectorLength, int vectorLength,
int stride) { int stride) {
// Flatten the vector out into the elements array // Flatten the vector out into the elements array
llvm::SmallVector<llvm::Constant *, ISPC_MAX_NVEC> elements; llvm::SmallVector<llvm::Constant *, ISPC_MAX_NVEC> elements;
@@ -1108,7 +1108,7 @@ lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
// is stride. If not, fail. // is stride. If not, fail.
for (int i = 1; i < vectorLength; ++i) { for (int i = 1; i < vectorLength; ++i) {
ci = llvm::dyn_cast<llvm::ConstantInt>(elements[i]); ci = llvm::dyn_cast<llvm::ConstantInt>(elements[i]);
if (ci == NULL) if (ci == NULL)
return false; return false;
int64_t nextVal = ci->getSExtValue(); int64_t nextVal = ci->getSExtValue();
@@ -1125,7 +1125,7 @@ lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
vector with values that increase by stride. vector with values that increase by stride.
*/ */
static bool static bool
lCheckMulForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength, lCheckMulForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
int stride, std::vector<llvm::PHINode *> &seenPhis) { int stride, std::vector<llvm::PHINode *> &seenPhis) {
// Is the first operand a constant integer value splatted across all of // Is the first operand a constant integer value splatted across all of
// the lanes? // the lanes?
@@ -1150,7 +1150,7 @@ lCheckMulForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
// Check to see if the other operand is a linear vector with stride // Check to see if the other operand is a linear vector with stride
// given by stride/splatVal. // given by stride/splatVal.
return lVectorIsLinear(op1, vectorLength, (int)(stride / splatVal), return lVectorIsLinear(op1, vectorLength, (int)(stride / splatVal),
seenPhis); seenPhis);
} }
@@ -1161,7 +1161,7 @@ lCheckMulForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
data. data.
*/ */
static bool static bool
lCheckAndForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength, lCheckAndForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
int stride, std::vector<llvm::PHINode *> &seenPhis) { int stride, std::vector<llvm::PHINode *> &seenPhis) {
// Require op1 to be a compile-time constant // Require op1 to be a compile-time constant
int64_t maskValue[ISPC_MAX_NVEC]; int64_t maskValue[ISPC_MAX_NVEC];
@@ -1359,7 +1359,7 @@ LLVMDumpValue(llvm::Value *v) {
static llvm::Value * static llvm::Value *
lExtractFirstVectorElement(llvm::Value *v, lExtractFirstVectorElement(llvm::Value *v,
std::map<llvm::PHINode *, llvm::PHINode *> &phiMap) { std::map<llvm::PHINode *, llvm::PHINode *> &phiMap) {
llvm::VectorType *vt = llvm::VectorType *vt =
llvm::dyn_cast<llvm::VectorType>(v->getType()); llvm::dyn_cast<llvm::VectorType>(v->getType());
@@ -1373,7 +1373,7 @@ lExtractFirstVectorElement(llvm::Value *v,
if (llvm::ConstantVector *cv = llvm::dyn_cast<llvm::ConstantVector>(v)) { if (llvm::ConstantVector *cv = llvm::dyn_cast<llvm::ConstantVector>(v)) {
return cv->getOperand(0); return cv->getOperand(0);
} }
if (llvm::ConstantDataVector *cdv = if (llvm::ConstantDataVector *cdv =
llvm::dyn_cast<llvm::ConstantDataVector>(v)) llvm::dyn_cast<llvm::ConstantDataVector>(v))
return cdv->getElementAsConstant(0); return cdv->getElementAsConstant(0);
@@ -1423,9 +1423,9 @@ lExtractFirstVectorElement(llvm::Value *v,
// The insertion point for the new phi node also has to be the // The insertion point for the new phi node also has to be the
// start of the bblock of the original phi node. // start of the bblock of the original phi node.
llvm::Instruction *phiInsertPos = phi->getParent()->begin(); llvm::Instruction *phiInsertPos = phi->getParent()->begin();
llvm::PHINode *scalarPhi = llvm::PHINode *scalarPhi =
llvm::PHINode::Create(vt->getElementType(), llvm::PHINode::Create(vt->getElementType(),
phi->getNumIncomingValues(), phi->getNumIncomingValues(),
newName, phiInsertPos); newName, phiInsertPos);
phiMap[phi] = scalarPhi; phiMap[phi] = scalarPhi;
@@ -1452,7 +1452,7 @@ lExtractFirstVectorElement(llvm::Value *v,
// have here. // have here.
llvm::Instruction *insertAfter = llvm::dyn_cast<llvm::Instruction>(v); llvm::Instruction *insertAfter = llvm::dyn_cast<llvm::Instruction>(v);
Assert(insertAfter != NULL); Assert(insertAfter != NULL);
llvm::Instruction *ee = llvm::Instruction *ee =
llvm::ExtractElementInst::Create(v, LLVMInt32(0), "first_elt", llvm::ExtractElementInst::Create(v, LLVMInt32(0), "first_elt",
(llvm::Instruction *)NULL); (llvm::Instruction *)NULL);
ee->insertAfter(insertAfter); ee->insertAfter(insertAfter);
@@ -1474,7 +1474,7 @@ LLVMExtractFirstVectorElement(llvm::Value *v) {
vector. vector.
*/ */
llvm::Value * llvm::Value *
LLVMConcatVectors(llvm::Value *v1, llvm::Value *v2, LLVMConcatVectors(llvm::Value *v1, llvm::Value *v2,
llvm::Instruction *insertBefore) { llvm::Instruction *insertBefore) {
Assert(v1->getType() == v2->getType()); Assert(v1->getType() == v2->getType());

View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file llvmutil.h /** @file llvmutil.h
@@ -59,7 +59,7 @@ namespace llvm {
/** This structure holds pointers to a variety of LLVM types; code /** This structure holds pointers to a variety of LLVM types; code
elsewhere can use them from here, ratherthan needing to make more elsewhere can use them from here, ratherthan needing to make more
verbose LLVM API calls. verbose LLVM API calls.
*/ */
struct LLVMTypes { struct LLVMTypes {
static llvm::Type *VoidType; static llvm::Type *VoidType;
static llvm::PointerType *VoidPointerType; static llvm::PointerType *VoidPointerType;
@@ -257,7 +257,7 @@ extern bool LLVMExtractVectorInts(llvm::Value *v, int64_t ret[], int *nElts);
and initializes the provided elements array such that the i'th and initializes the provided elements array such that the i'th
llvm::Value * in the array is the element that was inserted into the llvm::Value * in the array is the element that was inserted into the
i'th element of the vector. i'th element of the vector.
When the chain of insertelement instruction comes to an end, the only When the chain of insertelement instruction comes to an end, the only
base case that this function handles is the initial value being a base case that this function handles is the initial value being a
@@ -286,7 +286,7 @@ extern llvm::Value *LLVMExtractFirstVectorElement(llvm::Value *v);
/** This function takes two vectors, expected to be the same length, and /** This function takes two vectors, expected to be the same length, and
returns a new vector of twice the length that represents concatenating returns a new vector of twice the length that represents concatenating
the two of them. */ the two of them. */
extern llvm::Value *LLVMConcatVectors(llvm::Value *v1, llvm::Value *v2, extern llvm::Value *LLVMConcatVectors(llvm::Value *v1, llvm::Value *v2,
llvm::Instruction *insertBefore); llvm::Instruction *insertBefore);
/** This is a utility function for vector shuffling; it takes two vectors /** This is a utility function for vector shuffling; it takes two vectors

View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file main.cpp /** @file main.cpp
@@ -60,8 +60,8 @@
static void static void
lPrintVersion() { lPrintVersion() {
printf("Intel(r) SPMD Program Compiler (ispc), %s (build %s @ %s, LLVM %s)\n", printf("Intel(r) SPMD Program Compiler (ispc), %s (build %s @ %s, LLVM %s)\n",
ISPC_VERSION, BUILD_VERSION, BUILD_DATE, ISPC_VERSION, BUILD_VERSION, BUILD_DATE,
#if defined(LLVM_3_1) #if defined(LLVM_3_1)
"3.1" "3.1"
#elif defined(LLVM_3_2) #elif defined(LLVM_3_2)
@@ -70,7 +70,7 @@ lPrintVersion() {
"3.3" "3.3"
#else #else
#error "Unhandled LLVM version" #error "Unhandled LLVM version"
#endif #endif
); );
} }
@@ -82,7 +82,7 @@ usage(int ret) {
printf(" [--addressing={32,64}]\t\tSelect 32- or 64-bit addressing. (Note that 32-bit\n"); printf(" [--addressing={32,64}]\t\tSelect 32- or 64-bit addressing. (Note that 32-bit\n");
printf(" \t\taddressing calculations are done by default, even\n"); printf(" \t\taddressing calculations are done by default, even\n");
printf(" \t\ton 64-bit target architectures.)\n"); printf(" \t\ton 64-bit target architectures.)\n");
printf(" [--arch={%s}]\t\tSelect target architecture\n", printf(" [--arch={%s}]\t\tSelect target architecture\n",
Target::SupportedTargetArchs()); Target::SupportedTargetArchs());
printf(" [--c++-include-file=<name>]\t\tSpecify name of file to emit in #include statement in generated C++ code.\n"); printf(" [--c++-include-file=<name>]\t\tSpecify name of file to emit in #include statement in generated C++ code.\n");
#ifndef ISPC_IS_WINDOWS #ifndef ISPC_IS_WINDOWS
@@ -160,7 +160,7 @@ devUsage(int ret) {
/** We take arguments from both the command line as well as from the /** We take arguments from both the command line as well as from the
ISPC_ARGS environment variable. This function returns a new set of ISPC_ARGS environment variable. This function returns a new set of
arguments representing the ones from those two sources merged together. arguments representing the ones from those two sources merged together.
*/ */
static void lGetAllArgs(int Argc, char *Argv[], int &argc, char *argv[128]) { static void lGetAllArgs(int Argc, char *Argv[], int &argc, char *argv[128]) {
// Copy over the command line arguments (passed in) // Copy over the command line arguments (passed in)
for (int i = 0; i < Argc; ++i) for (int i = 0; i < Argc; ++i)
@@ -185,7 +185,7 @@ static void lGetAllArgs(int Argc, char *Argv[], int &argc, char *argv[128]) {
strncpy(ptr, env, len); strncpy(ptr, env, len);
ptr[len] = '\0'; ptr[len] = '\0';
// Add it to the args array and get out of here // Add it to the args array and get out of here
argv[argc++] = ptr; argv[argc++] = ptr;
if (*end == '\0') if (*end == '\0')
break; break;
@@ -403,7 +403,7 @@ int main(int Argc, char *Argv[]) {
g->opt.level = 0; g->opt.level = 0;
optSet = true; optSet = true;
} }
else if (!strcmp(argv[i], "-O") || !strcmp(argv[i], "-O1") || else if (!strcmp(argv[i], "-O") || !strcmp(argv[i], "-O1") ||
!strcmp(argv[i], "-O2") || !strcmp(argv[i], "-O3")) { !strcmp(argv[i], "-O2") || !strcmp(argv[i], "-O3")) {
g->opt.level = 1; g->opt.level = 1;
optSet = true; optSet = true;
@@ -480,7 +480,7 @@ int main(int Argc, char *Argv[]) {
int seed = getpid(); int seed = getpid();
#endif #endif
g->fuzzTestSeed = seed; g->fuzzTestSeed = seed;
Warning(SourcePos(), "Using seed %d for fuzz testing", Warning(SourcePos(), "Using seed %d for fuzz testing",
g->fuzzTestSeed); g->fuzzTestSeed);
} }
#ifdef ISPC_IS_WINDOWS #ifdef ISPC_IS_WINDOWS
@@ -490,7 +490,7 @@ int main(int Argc, char *Argv[]) {
#endif #endif
} }
if (outFileName == NULL && if (outFileName == NULL &&
headerFileName == NULL && headerFileName == NULL &&
depsFileName == NULL && depsFileName == NULL &&
hostStubFileName == NULL && hostStubFileName == NULL &&
@@ -500,9 +500,9 @@ int main(int Argc, char *Argv[]) {
"be issued, but no output will be generated."); "be issued, but no output will be generated.");
return Module::CompileAndOutput(file, arch, cpu, target, generatePIC, return Module::CompileAndOutput(file, arch, cpu, target, generatePIC,
ot, ot,
outFileName, outFileName,
headerFileName, headerFileName,
includeFileName, includeFileName,
depsFileName, depsFileName,
hostStubFileName, hostStubFileName,

View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file module.cpp /** @file module.cpp
@@ -163,7 +163,7 @@ lStripUnusedDebugInfo(llvm::Module *module) {
// And now loop over the subprograms inside each compile unit. // And now loop over the subprograms inside each compile unit.
for (unsigned j = 0, je = subprograms.getNumElements(); j != je; ++j) { for (unsigned j = 0, je = subprograms.getNumElements(); j != je; ++j) {
llvm::MDNode *spNode = llvm::MDNode *spNode =
llvm::dyn_cast<llvm::MDNode>(subprograms->getOperand(j)); llvm::dyn_cast<llvm::MDNode>(subprograms->getOperand(j));
Assert(spNode != NULL); Assert(spNode != NULL);
llvm::DISubprogram sp(spNode); llvm::DISubprogram sp(spNode);
@@ -197,7 +197,7 @@ lStripUnusedDebugInfo(llvm::Module *module) {
// debugging metadata organization on the LLVM side changed, // debugging metadata organization on the LLVM side changed,
// here is a bunch of asserting to make sure that element 12 of // here is a bunch of asserting to make sure that element 12 of
// the compile unit's MDNode has the subprograms array.... // the compile unit's MDNode has the subprograms array....
llvm::MDNode *nodeSPMD = llvm::MDNode *nodeSPMD =
llvm::dyn_cast<llvm::MDNode>(cuNode->getOperand(12)); llvm::dyn_cast<llvm::MDNode>(cuNode->getOperand(12));
Assert(nodeSPMD != NULL); Assert(nodeSPMD != NULL);
llvm::MDNode *nodeSPMDArray = llvm::MDNode *nodeSPMDArray =
@@ -209,9 +209,9 @@ lStripUnusedDebugInfo(llvm::Module *module) {
// And now we can go and stuff it into the node with some // And now we can go and stuff it into the node with some
// confidence... // confidence...
llvm::Value *usedSubprogramsArray = llvm::Value *usedSubprogramsArray =
m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(usedSubprograms)); m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(usedSubprograms));
llvm::MDNode *replNode = llvm::MDNode *replNode =
llvm::MDNode::get(*g->ctx, llvm::ArrayRef<llvm::Value *>(usedSubprogramsArray)); llvm::MDNode::get(*g->ctx, llvm::ArrayRef<llvm::Value *>(usedSubprogramsArray));
cuNode->replaceOperandWith(12, replNode); cuNode->replaceOperandWith(12, replNode);
} }
@@ -349,7 +349,7 @@ Module::CompileFile() {
else { else {
// No preprocessor, just open up the file if it's not stdin.. // No preprocessor, just open up the file if it's not stdin..
FILE* f = NULL; FILE* f = NULL;
if (filename == NULL) if (filename == NULL)
f = stdin; f = stdin;
else { else {
f = fopen(filename, "r"); f = fopen(filename, "r");
@@ -383,7 +383,7 @@ Module::AddTypeDef(const std::string &name, const Type *type,
void void
Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initExpr, Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initExpr,
bool isConst, StorageClass storageClass, SourcePos pos) { bool isConst, StorageClass storageClass, SourcePos pos) {
// These may be NULL due to errors in parsing; just gracefully return // These may be NULL due to errors in parsing; just gracefully return
// here if so. // here if so.
@@ -420,7 +420,7 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
"expression."); "expression.");
return; return;
} }
llvm::Type *llvmType = type->LLVMType(g->ctx); llvm::Type *llvmType = type->LLVMType(g->ctx);
if (llvmType == NULL) if (llvmType == NULL)
return; return;
@@ -444,7 +444,7 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
// convert themselves anyway.) // convert themselves anyway.)
if (dynamic_cast<ExprList *>(initExpr) == NULL) if (dynamic_cast<ExprList *>(initExpr) == NULL)
initExpr = TypeConvertExpr(initExpr, type, "initializer"); initExpr = TypeConvertExpr(initExpr, type, "initializer");
if (initExpr != NULL) { if (initExpr != NULL) {
initExpr = Optimize(initExpr); initExpr = Optimize(initExpr);
// Fingers crossed, now let's see if we've got a // Fingers crossed, now let's see if we've got a
@@ -481,21 +481,21 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
// If the type doesn't match with the previous one, issue an error. // If the type doesn't match with the previous one, issue an error.
if (!Type::Equal(sym->type, type) || if (!Type::Equal(sym->type, type) ||
(sym->storageClass != SC_EXTERN && (sym->storageClass != SC_EXTERN &&
sym->storageClass != SC_EXTERN_C && sym->storageClass != SC_EXTERN_C &&
sym->storageClass != storageClass)) { sym->storageClass != storageClass)) {
Error(pos, "Definition of variable \"%s\" conflicts with " Error(pos, "Definition of variable \"%s\" conflicts with "
"definition at %s:%d.", name.c_str(), "definition at %s:%d.", name.c_str(),
sym->pos.name, sym->pos.first_line); sym->pos.name, sym->pos.first_line);
return; return;
} }
llvm::GlobalVariable *gv = llvm::GlobalVariable *gv =
llvm::dyn_cast<llvm::GlobalVariable>(sym->storagePtr); llvm::dyn_cast<llvm::GlobalVariable>(sym->storagePtr);
Assert(gv != NULL); Assert(gv != NULL);
// And issue an error if this is a redefinition of a variable // And issue an error if this is a redefinition of a variable
if (gv->hasInitializer() && if (gv->hasInitializer() &&
sym->storageClass != SC_EXTERN && sym->storageClass != SC_EXTERN_C) { sym->storageClass != SC_EXTERN && sym->storageClass != SC_EXTERN_C) {
Error(pos, "Redefinition of variable \"%s\" is illegal. " Error(pos, "Redefinition of variable \"%s\" is illegal. "
"(Previous definition at %s:%d.)", sym->name.c_str(), "(Previous definition at %s:%d.)", sym->name.c_str(),
@@ -521,8 +521,8 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
// Note that the NULL llvmInitializer is what leads to "extern" // Note that the NULL llvmInitializer is what leads to "extern"
// declarations coming up extern and not defining storage (a bit // declarations coming up extern and not defining storage (a bit
// subtle)... // subtle)...
sym->storagePtr = new llvm::GlobalVariable(*module, llvmType, isConst, sym->storagePtr = new llvm::GlobalVariable(*module, llvmType, isConst,
linkage, llvmInitializer, linkage, llvmInitializer,
sym->name.c_str()); sym->name.c_str());
// Patch up any references to the previous GlobalVariable (e.g. from a // Patch up any references to the previous GlobalVariable (e.g. from a
@@ -532,11 +532,11 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
oldGV->removeFromParent(); oldGV->removeFromParent();
sym->storagePtr->setName(sym->name.c_str()); sym->storagePtr->setName(sym->name.c_str());
} }
if (diBuilder) { if (diBuilder) {
llvm::DIFile file = pos.GetDIFile(); llvm::DIFile file = pos.GetDIFile();
llvm::DIGlobalVariable var = llvm::DIGlobalVariable var =
diBuilder->createGlobalVariable(name, diBuilder->createGlobalVariable(name,
file, file,
pos.first_line, pos.first_line,
sym->type->GetDIType(file), sym->type->GetDIType(file),
@@ -555,10 +555,10 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
(Note that it's fine for the original struct or a contained struct to (Note that it's fine for the original struct or a contained struct to
be varying, so long as all of its members have bound 'uniform' be varying, so long as all of its members have bound 'uniform'
variability.) variability.)
This functions returns true and issues an error if are any illegal This functions returns true and issues an error if are any illegal
types are found and returns false otherwise. types are found and returns false otherwise.
*/ */
static bool static bool
lRecursiveCheckValidParamType(const Type *t, bool vectorOk) { lRecursiveCheckValidParamType(const Type *t, bool vectorOk) {
@@ -601,7 +601,7 @@ lRecursiveCheckValidParamType(const Type *t, bool vectorOk) {
varying parameters is illegal. varying parameters is illegal.
*/ */
static void static void
lCheckExportedParameterTypes(const Type *type, const std::string &name, lCheckExportedParameterTypes(const Type *type, const std::string &name,
SourcePos pos) { SourcePos pos) {
if (lRecursiveCheckValidParamType(type, false) == false) { if (lRecursiveCheckValidParamType(type, false) == false) {
if (CastType<PointerType>(type)) if (CastType<PointerType>(type))
@@ -645,8 +645,8 @@ lCheckForStructParameters(const FunctionType *ftype, SourcePos pos) {
false if any errors were encountered. false if any errors were encountered.
*/ */
void void
Module::AddFunctionDeclaration(const std::string &name, Module::AddFunctionDeclaration(const std::string &name,
const FunctionType *functionType, const FunctionType *functionType,
StorageClass storageClass, bool isInline, StorageClass storageClass, bool isInline,
SourcePos pos) { SourcePos pos) {
Assert(functionType != NULL); Assert(functionType != NULL);
@@ -666,7 +666,7 @@ Module::AddFunctionDeclaration(const std::string &name,
for (unsigned int i = 0; i < overloadFuncs.size(); ++i) { for (unsigned int i = 0; i < overloadFuncs.size(); ++i) {
Symbol *overloadFunc = overloadFuncs[i]; Symbol *overloadFunc = overloadFuncs[i];
const FunctionType *overloadType = const FunctionType *overloadType =
CastType<FunctionType>(overloadFunc->type); CastType<FunctionType>(overloadFunc->type);
if (overloadType == NULL) { if (overloadType == NULL) {
Assert(m->errorCount == 0); Assert(m->errorCount == 0);
@@ -688,7 +688,7 @@ Module::AddFunctionDeclaration(const std::string &name,
// If all of the parameter types match but the return type is // If all of the parameter types match but the return type is
// different, return an error--overloading by return type isn't // different, return an error--overloading by return type isn't
// allowed. // allowed.
const FunctionType *ofType = const FunctionType *ofType =
CastType<FunctionType>(overloadFunc->type); CastType<FunctionType>(overloadFunc->type);
Assert(ofType != NULL); Assert(ofType != NULL);
if (ofType->GetNumParameters() == functionType->GetNumParameters()) { if (ofType->GetNumParameters() == functionType->GetNumParameters()) {
@@ -725,7 +725,7 @@ Module::AddFunctionDeclaration(const std::string &name,
symbolTable->LookupFunction(name.c_str(), &funcs); symbolTable->LookupFunction(name.c_str(), &funcs);
if (funcs.size() > 0) { if (funcs.size() > 0) {
if (funcs.size() > 1) { if (funcs.size() > 1) {
// Multiple functions with this name have already been declared; // Multiple functions with this name have already been declared;
// can't overload here // can't overload here
Error(pos, "Can't overload extern \"C\" function \"%s\"; " Error(pos, "Can't overload extern \"C\" function \"%s\"; "
"%d functions with the same name have already been declared.", "%d functions with the same name have already been declared.",
@@ -747,7 +747,7 @@ Module::AddFunctionDeclaration(const std::string &name,
// Get the LLVM FunctionType // Get the LLVM FunctionType
bool disableMask = (storageClass == SC_EXTERN_C); bool disableMask = (storageClass == SC_EXTERN_C);
llvm::FunctionType *llvmFunctionType = llvm::FunctionType *llvmFunctionType =
functionType->LLVMFunctionType(g->ctx, disableMask); functionType->LLVMFunctionType(g->ctx, disableMask);
if (llvmFunctionType == NULL) if (llvmFunctionType == NULL)
return; return;
@@ -763,13 +763,13 @@ Module::AddFunctionDeclaration(const std::string &name,
if (g->mangleFunctionsWithTarget) if (g->mangleFunctionsWithTarget)
functionName += g->target.GetISAString(); functionName += g->target.GetISAString();
} }
llvm::Function *function = llvm::Function *function =
llvm::Function::Create(llvmFunctionType, linkage, functionName.c_str(), llvm::Function::Create(llvmFunctionType, linkage, functionName.c_str(),
module); module);
// Set function attributes: we never throw exceptions // Set function attributes: we never throw exceptions
function->setDoesNotThrow(); function->setDoesNotThrow();
if (storageClass != SC_EXTERN_C && if (storageClass != SC_EXTERN_C &&
!g->generateDebuggingSymbols && !g->generateDebuggingSymbols &&
isInline) isInline)
#ifdef LLVM_3_2 #ifdef LLVM_3_2
@@ -778,7 +778,7 @@ Module::AddFunctionDeclaration(const std::string &name,
function->addFnAttr(llvm::Attribute::AlwaysInline); function->addFnAttr(llvm::Attribute::AlwaysInline);
#endif #endif
if (functionType->isTask) if (functionType->isTask)
// This also applies transitively to members I think? // This also applies transitively to members I think?
#if defined(LLVM_3_1) #if defined(LLVM_3_1)
function->setDoesNotAlias(1, true); function->setDoesNotAlias(1, true);
#else #else
@@ -791,12 +791,12 @@ Module::AddFunctionDeclaration(const std::string &name,
// Make sure that the return type isn't 'varying' or vector typed if // Make sure that the return type isn't 'varying' or vector typed if
// the function is 'export'ed. // the function is 'export'ed.
if (functionType->isExported && if (functionType->isExported &&
lRecursiveCheckValidParamType(functionType->GetReturnType(), false) == false) lRecursiveCheckValidParamType(functionType->GetReturnType(), false) == false)
Error(pos, "Illegal to return a \"varying\" or vector type from " Error(pos, "Illegal to return a \"varying\" or vector type from "
"exported function \"%s\"", name.c_str()); "exported function \"%s\"", name.c_str());
if (functionType->isTask && if (functionType->isTask &&
Type::Equal(functionType->GetReturnType(), AtomicType::Void) == false) Type::Equal(functionType->GetReturnType(), AtomicType::Void) == false)
Error(pos, "Task-qualified functions must have void return type."); Error(pos, "Task-qualified functions must have void return type.");
@@ -822,7 +822,7 @@ Module::AddFunctionDeclaration(const std::string &name,
// specify when this is not the case, but this should be the // specify when this is not the case, but this should be the
// default.) Set parameter attributes accordingly. (Only for // default.) Set parameter attributes accordingly. (Only for
// uniform pointers, since varying pointers are int vectors...) // uniform pointers, since varying pointers are int vectors...)
if (!functionType->isTask && if (!functionType->isTask &&
((CastType<PointerType>(argType) != NULL && ((CastType<PointerType>(argType) != NULL &&
argType->IsUniformType() && argType->IsUniformType() &&
// Exclude SOA argument because it is a pair {struct *, int} // Exclude SOA argument because it is a pair {struct *, int}
@@ -849,7 +849,7 @@ Module::AddFunctionDeclaration(const std::string &name,
if (symbolTable->LookupFunction(argName.c_str())) if (symbolTable->LookupFunction(argName.c_str()))
Warning(argPos, "Function parameter \"%s\" shadows a function " Warning(argPos, "Function parameter \"%s\" shadows a function "
"declared in global scope.", argName.c_str()); "declared in global scope.", argName.c_str());
if (defaultValue != NULL) if (defaultValue != NULL)
seenDefaultArg = true; seenDefaultArg = true;
else if (seenDefaultArg) { else if (seenDefaultArg) {
@@ -894,7 +894,7 @@ Module::AddFunctionDefinition(const std::string &name, const FunctionType *type,
// we need to override the function type here in case the function had // we need to override the function type here in case the function had
// earlier been declared with anonymous parameter names but is now // earlier been declared with anonymous parameter names but is now
// defined with actual names. This is yet another reason we shouldn't // defined with actual names. This is yet another reason we shouldn't
// include the names in FunctionType... // include the names in FunctionType...
sym->type = type; sym->type = type;
ast->AddFunction(sym, code); ast->AddFunction(sym, code);
@@ -902,14 +902,14 @@ Module::AddFunctionDefinition(const std::string &name, const FunctionType *type,
void void
Module::AddExportedTypes(const std::vector<std::pair<const Type *, Module::AddExportedTypes(const std::vector<std::pair<const Type *,
SourcePos> > &types) { SourcePos> > &types) {
for (int i = 0; i < (int)types.size(); ++i) { for (int i = 0; i < (int)types.size(); ++i) {
if (CastType<StructType>(types[i].first) == NULL && if (CastType<StructType>(types[i].first) == NULL &&
CastType<VectorType>(types[i].first) == NULL && CastType<VectorType>(types[i].first) == NULL &&
CastType<EnumType>(types[i].first) == NULL) CastType<EnumType>(types[i].first) == NULL)
Error(types[i].second, "Only struct, vector, and enum types, " Error(types[i].second, "Only struct, vector, and enum types, "
"not \"%s\", are allowed in type export lists.", "not \"%s\", are allowed in type export lists.",
types[i].first->GetString().c_str()); types[i].first->GetString().c_str());
else else
exportedTypes.push_back(types[i]); exportedTypes.push_back(types[i]);
@@ -996,7 +996,7 @@ Module::writeOutput(OutputType outputType, const char *outFileName,
"C++ emission."); "C++ emission.");
return false; return false;
} }
extern bool WriteCXXFile(llvm::Module *module, const char *fn, extern bool WriteCXXFile(llvm::Module *module, const char *fn,
int vectorWidth, const char *includeName); int vectorWidth, const char *includeName);
return WriteCXXFile(module, outFileName, g->target.vectorWidth, return WriteCXXFile(module, outFileName, g->target.vectorWidth,
includeFileName); includeFileName);
@@ -1044,11 +1044,11 @@ Module::writeObjectFileOrAssembly(OutputType outputType, const char *outFileName
bool bool
Module::writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine, Module::writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
llvm::Module *module, OutputType outputType, llvm::Module *module, OutputType outputType,
const char *outFileName) { const char *outFileName) {
// Figure out if we're generating object file or assembly output, and // Figure out if we're generating object file or assembly output, and
// set binary output for object files // set binary output for object files
llvm::TargetMachine::CodeGenFileType fileType = (outputType == Object) ? llvm::TargetMachine::CodeGenFileType fileType = (outputType == Object) ?
llvm::TargetMachine::CGFT_ObjectFile : llvm::TargetMachine::CGFT_AssemblyFile; llvm::TargetMachine::CGFT_ObjectFile : llvm::TargetMachine::CGFT_AssemblyFile;
bool binary = (fileType == llvm::TargetMachine::CGFT_ObjectFile); bool binary = (fileType == llvm::TargetMachine::CGFT_ObjectFile);
unsigned int flags = binary ? llvm::raw_fd_ostream::F_Binary : 0; unsigned int flags = binary ? llvm::raw_fd_ostream::F_Binary : 0;
@@ -1083,7 +1083,7 @@ Module::writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
// Finally, run the passes to emit the object file/assembly // Finally, run the passes to emit the object file/assembly
pm.run(*module); pm.run(*module);
// Success; tell tool_output_file to keep the final output file. // Success; tell tool_output_file to keep the final output file.
of->keep(); of->keep();
return true; return true;
@@ -1123,7 +1123,7 @@ lEmitStructDecl(const StructType *st, std::vector<const StructType *> *emittedSt
// Otherwise first make sure any contained structs have been declared. // Otherwise first make sure any contained structs have been declared.
for (int i = 0; i < st->GetElementCount(); ++i) { for (int i = 0; i < st->GetElementCount(); ++i) {
const StructType *elementStructType = const StructType *elementStructType =
lGetElementStructType(st->GetElementType(i)); lGetElementStructType(st->GetElementType(i));
if (elementStructType != NULL) if (elementStructType != NULL)
lEmitStructDecl(elementStructType, emittedStructs, file); lEmitStructDecl(elementStructType, emittedStructs, file);
@@ -1172,14 +1172,14 @@ lEmitEnumDecls(const std::vector<const EnumType *> &enumTypes, FILE *file) {
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n"); fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
fprintf(file, "// Enumerator types with external visibility from ispc code\n"); fprintf(file, "// Enumerator types with external visibility from ispc code\n");
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n\n"); fprintf(file, "///////////////////////////////////////////////////////////////////////////\n\n");
for (unsigned int i = 0; i < enumTypes.size(); ++i) { for (unsigned int i = 0; i < enumTypes.size(); ++i) {
fprintf(file, "#ifndef __ISPC_ENUM_%s__\n",enumTypes[i]->GetEnumName().c_str()); fprintf(file, "#ifndef __ISPC_ENUM_%s__\n",enumTypes[i]->GetEnumName().c_str());
fprintf(file, "#define __ISPC_ENUM_%s__\n",enumTypes[i]->GetEnumName().c_str()); fprintf(file, "#define __ISPC_ENUM_%s__\n",enumTypes[i]->GetEnumName().c_str());
std::string declaration = enumTypes[i]->GetCDeclaration(""); std::string declaration = enumTypes[i]->GetCDeclaration("");
fprintf(file, "%s {\n", declaration.c_str()); fprintf(file, "%s {\n", declaration.c_str());
// Print the individual enumerators // Print the individual enumerators
for (int j = 0; j < enumTypes[i]->GetEnumeratorCount(); ++j) { for (int j = 0; j < enumTypes[i]->GetEnumeratorCount(); ++j) {
const Symbol *e = enumTypes[i]->GetEnumerator(j); const Symbol *e = enumTypes[i]->GetEnumerator(j);
Assert(e->constValue != NULL); Assert(e->constValue != NULL);
@@ -1233,7 +1233,7 @@ lEmitVectorTypedefs(const std::vector<const VectorType *> &types, FILE *file) {
fprintf(file, "struct %s%d { %s v[%d]; };\n", baseDecl.c_str(), size, fprintf(file, "struct %s%d { %s v[%d]; };\n", baseDecl.c_str(), size,
baseDecl.c_str(), size); baseDecl.c_str(), size);
fprintf(file, "#else\n"); fprintf(file, "#else\n");
fprintf(file, "struct %s%d { %s v[%d]; } __attribute__ ((aligned(%d)));\n", fprintf(file, "struct %s%d { %s v[%d]; } __attribute__ ((aligned(%d)));\n",
baseDecl.c_str(), size, baseDecl.c_str(), size, align); baseDecl.c_str(), size, baseDecl.c_str(), size, align);
fprintf(file, "#endif\n"); fprintf(file, "#endif\n");
fprintf(file, "#endif\n\n"); fprintf(file, "#endif\n\n");
@@ -1265,7 +1265,7 @@ lAddTypeIfNew(const Type *type, std::vector<const T *> *exportedTypes) {
Then, if it's a struct, recursively process its members to do the same. Then, if it's a struct, recursively process its members to do the same.
*/ */
static void static void
lGetExportedTypes(const Type *type, lGetExportedTypes(const Type *type,
std::vector<const StructType *> *exportedStructTypes, std::vector<const StructType *> *exportedStructTypes,
std::vector<const EnumType *> *exportedEnumTypes, std::vector<const EnumType *> *exportedEnumTypes,
std::vector<const VectorType *> *exportedVectorTypes) { std::vector<const VectorType *> *exportedVectorTypes) {
@@ -1273,13 +1273,13 @@ lGetExportedTypes(const Type *type,
const StructType *structType = CastType<StructType>(type); const StructType *structType = CastType<StructType>(type);
if (CastType<ReferenceType>(type) != NULL) if (CastType<ReferenceType>(type) != NULL)
lGetExportedTypes(type->GetReferenceTarget(), exportedStructTypes, lGetExportedTypes(type->GetReferenceTarget(), exportedStructTypes,
exportedEnumTypes, exportedVectorTypes); exportedEnumTypes, exportedVectorTypes);
else if (CastType<PointerType>(type) != NULL) else if (CastType<PointerType>(type) != NULL)
lGetExportedTypes(type->GetBaseType(), exportedStructTypes, lGetExportedTypes(type->GetBaseType(), exportedStructTypes,
exportedEnumTypes, exportedVectorTypes); exportedEnumTypes, exportedVectorTypes);
else if (arrayType != NULL) else if (arrayType != NULL)
lGetExportedTypes(arrayType->GetElementType(), exportedStructTypes, lGetExportedTypes(arrayType->GetElementType(), exportedStructTypes,
exportedEnumTypes, exportedVectorTypes); exportedEnumTypes, exportedVectorTypes);
else if (structType != NULL) { else if (structType != NULL) {
lAddTypeIfNew(type, exportedStructTypes); lAddTypeIfNew(type, exportedStructTypes);
@@ -1303,7 +1303,7 @@ lGetExportedTypes(const Type *type,
present in the parameters to them. present in the parameters to them.
*/ */
static void static void
lGetExportedParamTypes(const std::vector<Symbol *> &funcs, lGetExportedParamTypes(const std::vector<Symbol *> &funcs,
std::vector<const StructType *> *exportedStructTypes, std::vector<const StructType *> *exportedStructTypes,
std::vector<const EnumType *> *exportedEnumTypes, std::vector<const EnumType *> *exportedEnumTypes,
std::vector<const VectorType *> *exportedVectorTypes) { std::vector<const VectorType *> *exportedVectorTypes) {
@@ -1383,7 +1383,7 @@ std::string emitOffloadParamStruct(const std::string &paramStructName,
{ {
std::stringstream out; std::stringstream out;
out << "struct " << paramStructName << " {" << std::endl; out << "struct " << paramStructName << " {" << std::endl;
for (int i=0;i<fct->GetNumParameters();i++) { for (int i=0;i<fct->GetNumParameters();i++) {
const Type *orgParamType = fct->GetParameterType(i); const Type *orgParamType = fct->GetParameterType(i);
if (orgParamType->IsPointerType() || orgParamType->IsArrayType()) { if (orgParamType->IsPointerType() || orgParamType->IsArrayType()) {
@@ -1405,7 +1405,7 @@ std::string emitOffloadParamStruct(const std::string &paramStructName,
} }
std::string paramName = fct->GetParameterName(i); std::string paramName = fct->GetParameterName(i);
std::string paramTypeName = paramType->GetString(); std::string paramTypeName = paramType->GetString();
std::string tmpArgDecl = paramType->GetCDeclaration(paramName); std::string tmpArgDecl = paramType->GetCDeclaration(paramName);
out << " " << tmpArgDecl << ";" << std::endl; out << " " << tmpArgDecl << ";" << std::endl;
} }
@@ -1415,7 +1415,7 @@ std::string emitOffloadParamStruct(const std::string &paramStructName,
} }
bool bool
Module::writeDevStub(const char *fn) Module::writeDevStub(const char *fn)
{ {
FILE *file = fopen(fn, "w"); FILE *file = fopen(fn, "w");
if (!file) { if (!file) {
@@ -1427,14 +1427,14 @@ Module::writeDevStub(const char *fn)
fprintf(file,"#include \"ispc/dev/offload.h\"\n\n"); fprintf(file,"#include \"ispc/dev/offload.h\"\n\n");
fprintf(file, "#include <stdint.h>\n\n"); fprintf(file, "#include <stdint.h>\n\n");
// Collect single linear arrays of the *exported* functions (we'll // Collect single linear arrays of the *exported* functions (we'll
// treat those as "__kernel"s in IVL -- "extern" functions will only // treat those as "__kernel"s in IVL -- "extern" functions will only
// be used for dev-dev function calls; only "export" functions will // be used for dev-dev function calls; only "export" functions will
// get exported to the host // get exported to the host
std::vector<Symbol *> exportedFuncs; std::vector<Symbol *> exportedFuncs;
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs); m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
// Get all of the struct, vector, and enumerant types used as function // Get all of the struct, vector, and enumerant types used as function
// parameters. These vectors may have repeats. // parameters. These vectors may have repeats.
std::vector<const StructType *> exportedStructTypes; std::vector<const StructType *> exportedStructTypes;
@@ -1442,12 +1442,12 @@ Module::writeDevStub(const char *fn)
std::vector<const VectorType *> exportedVectorTypes; std::vector<const VectorType *> exportedVectorTypes;
lGetExportedParamTypes(exportedFuncs, &exportedStructTypes, lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
&exportedEnumTypes, &exportedVectorTypes); &exportedEnumTypes, &exportedVectorTypes);
// And print them // And print them
lEmitVectorTypedefs(exportedVectorTypes, file); lEmitVectorTypedefs(exportedVectorTypes, file);
lEmitEnumDecls(exportedEnumTypes, file); lEmitEnumDecls(exportedEnumTypes, file);
lEmitStructDecls(exportedStructTypes, file); lEmitStructDecls(exportedStructTypes, file);
fprintf(file, "#ifdef __cplusplus\n"); fprintf(file, "#ifdef __cplusplus\n");
fprintf(file, "namespace ispc {\n"); fprintf(file, "namespace ispc {\n");
fprintf(file, "#endif // __cplusplus\n"); fprintf(file, "#endif // __cplusplus\n");
@@ -1475,7 +1475,7 @@ Module::writeDevStub(const char *fn)
Assert(sym); Assert(sym);
const FunctionType *fct = CastType<FunctionType>(sym->type); const FunctionType *fct = CastType<FunctionType>(sym->type);
Assert(fct); Assert(fct);
if (!fct->GetReturnType()->IsVoidType()) { if (!fct->GetReturnType()->IsVoidType()) {
//Error(sym->pos,"When emitting offload-stubs, \"export\"ed functions cannot have non-void return types.\n"); //Error(sym->pos,"When emitting offload-stubs, \"export\"ed functions cannot have non-void return types.\n");
Warning(sym->pos,"When emitting offload-stubs, ignoring \"export\"ed function with non-void return types.\n"); Warning(sym->pos,"When emitting offload-stubs, ignoring \"export\"ed function with non-void return types.\n");
@@ -1505,7 +1505,7 @@ Module::writeDevStub(const char *fn)
fprintf(file," struct %s args;\n memcpy(&args,in_pMiscData,sizeof(args));\n", fprintf(file," struct %s args;\n memcpy(&args,in_pMiscData,sizeof(args));\n",
paramStructName.c_str()); paramStructName.c_str());
std::stringstream funcall; std::stringstream funcall;
funcall << "ispc::" << sym->name << "("; funcall << "ispc::" << sym->name << "(";
for (int i=0;i<fct->GetNumParameters();i++) { for (int i=0;i<fct->GetNumParameters();i++) {
// get param type and make it non-const, so we can write while unpacking // get param type and make it non-const, so we can write while unpacking
@@ -1522,7 +1522,7 @@ Module::writeDevStub(const char *fn)
} else { } else {
paramType = orgParamType->GetAsNonConstType(); paramType = orgParamType->GetAsNonConstType();
} }
std::string paramName = fct->GetParameterName(i); std::string paramName = fct->GetParameterName(i);
std::string paramTypeName = paramType->GetString(); std::string paramTypeName = paramType->GetString();
@@ -1554,7 +1554,7 @@ Module::writeDevStub(const char *fn)
bool bool
Module::writeHostStub(const char *fn) Module::writeHostStub(const char *fn)
{ {
FILE *file = fopen(fn, "w"); FILE *file = fopen(fn, "w");
if (!file) { if (!file) {
@@ -1568,14 +1568,14 @@ Module::writeHostStub(const char *fn)
//fprintf(file,"#ifdef __cplusplus\nextern \"C\" {\n#endif // __cplusplus\n"); //fprintf(file,"#ifdef __cplusplus\nextern \"C\" {\n#endif // __cplusplus\n");
fprintf(file, "#ifdef __cplusplus\nnamespace ispc {\n#endif // __cplusplus\n\n"); fprintf(file, "#ifdef __cplusplus\nnamespace ispc {\n#endif // __cplusplus\n\n");
// Collect single linear arrays of the *exported* functions (we'll // Collect single linear arrays of the *exported* functions (we'll
// treat those as "__kernel"s in IVL -- "extern" functions will only // treat those as "__kernel"s in IVL -- "extern" functions will only
// be used for dev-dev function calls; only "export" functions will // be used for dev-dev function calls; only "export" functions will
// get exported to the host // get exported to the host
std::vector<Symbol *> exportedFuncs; std::vector<Symbol *> exportedFuncs;
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs); m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
// Get all of the struct, vector, and enumerant types used as function // Get all of the struct, vector, and enumerant types used as function
// parameters. These vectors may have repeats. // parameters. These vectors may have repeats.
std::vector<const StructType *> exportedStructTypes; std::vector<const StructType *> exportedStructTypes;
@@ -1583,12 +1583,12 @@ Module::writeHostStub(const char *fn)
std::vector<const VectorType *> exportedVectorTypes; std::vector<const VectorType *> exportedVectorTypes;
lGetExportedParamTypes(exportedFuncs, &exportedStructTypes, lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
&exportedEnumTypes, &exportedVectorTypes); &exportedEnumTypes, &exportedVectorTypes);
// And print them // And print them
lEmitVectorTypedefs(exportedVectorTypes, file); lEmitVectorTypedefs(exportedVectorTypes, file);
lEmitEnumDecls(exportedEnumTypes, file); lEmitEnumDecls(exportedEnumTypes, file);
lEmitStructDecls(exportedStructTypes, file); lEmitStructDecls(exportedStructTypes, file);
fprintf(file, "\n"); fprintf(file, "\n");
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n"); fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
fprintf(file, "// host-side stubs for dev-side ISPC fucntion(s)\n"); fprintf(file, "// host-side stubs for dev-side ISPC fucntion(s)\n");
@@ -1615,7 +1615,7 @@ Module::writeHostStub(const char *fn)
// ------------------------------------------------------- // -------------------------------------------------------
// then, emit a fct stub that unpacks the parameters and pointers // then, emit a fct stub that unpacks the parameters and pointers
// ------------------------------------------------------- // -------------------------------------------------------
std::string decl = fct->GetCDeclaration(sym->name); std::string decl = fct->GetCDeclaration(sym->name);
fprintf(file, "extern %s {\n", decl.c_str()); fprintf(file, "extern %s {\n", decl.c_str());
int numPointers = 0; int numPointers = 0;
@@ -1661,7 +1661,7 @@ Module::writeHostStub(const char *fn)
numPointers); numPointers);
fprintf(file,"}\n\n"); fprintf(file,"}\n\n");
} }
// end extern "C" // end extern "C"
fprintf(file, "#ifdef __cplusplus\n"); fprintf(file, "#ifdef __cplusplus\n");
fprintf(file, "}/* namespace */\n"); fprintf(file, "}/* namespace */\n");
@@ -1669,7 +1669,7 @@ Module::writeHostStub(const char *fn)
// fprintf(file, "#ifdef __cplusplus\n"); // fprintf(file, "#ifdef __cplusplus\n");
// fprintf(file, "}/* end extern C */\n"); // fprintf(file, "}/* end extern C */\n");
// fprintf(file, "#endif // __cplusplus\n"); // fprintf(file, "#endif // __cplusplus\n");
fclose(file); fclose(file);
return true; return true;
} }
@@ -1690,9 +1690,9 @@ Module::writeHeader(const char *fn) {
std::string guard = "ISPC_"; std::string guard = "ISPC_";
const char *p = fn; const char *p = fn;
while (*p) { while (*p) {
if (isdigit(*p)) if (isdigit(*p))
guard += *p; guard += *p;
else if (isalpha(*p)) else if (isalpha(*p))
guard += toupper(*p); guard += toupper(*p);
else else
guard += "_"; guard += "_";
@@ -1719,7 +1719,7 @@ Module::writeHeader(const char *fn) {
std::vector<Symbol *> exportedFuncs, externCFuncs; std::vector<Symbol *> exportedFuncs, externCFuncs;
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs); m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
m->symbolTable->GetMatchingFunctions(lIsExternC, &externCFuncs); m->symbolTable->GetMatchingFunctions(lIsExternC, &externCFuncs);
// Get all of the struct, vector, and enumerant types used as function // Get all of the struct, vector, and enumerant types used as function
// parameters. These vectors may have repeats. // parameters. These vectors may have repeats.
std::vector<const StructType *> exportedStructTypes; std::vector<const StructType *> exportedStructTypes;
@@ -1795,10 +1795,10 @@ Module::execPreprocessor(const char *infilename, llvm::raw_string_ostream *ostre
#endif #endif
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs(new clang::DiagnosticIDs); llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs(new clang::DiagnosticIDs);
#if defined(LLVM_3_1) #if defined(LLVM_3_1)
clang::DiagnosticsEngine *diagEngine = clang::DiagnosticsEngine *diagEngine =
new clang::DiagnosticsEngine(diagIDs, diagPrinter); new clang::DiagnosticsEngine(diagIDs, diagPrinter);
#else #else
clang::DiagnosticsEngine *diagEngine = clang::DiagnosticsEngine *diagEngine =
new clang::DiagnosticsEngine(diagIDs, diagOptions, diagPrinter); new clang::DiagnosticsEngine(diagIDs, diagOptions, diagPrinter);
#endif #endif
inst.setDiagnostics(diagEngine); inst.setDiagnostics(diagEngine);
@@ -1843,7 +1843,7 @@ Module::execPreprocessor(const char *infilename, llvm::raw_string_ostream *ostre
headerOpts.Verbose = 1; headerOpts.Verbose = 1;
for (int i = 0; i < (int)g->includePath.size(); ++i) { for (int i = 0; i < (int)g->includePath.size(); ++i) {
headerOpts.AddPath(g->includePath[i], clang::frontend::Angled, headerOpts.AddPath(g->includePath[i], clang::frontend::Angled,
#if !defined(LLVM_3_3) #if !defined(LLVM_3_3)
true /* is user supplied */, true /* is user supplied */,
#endif #endif
false /* not a framework */, false /* not a framework */,
@@ -1884,7 +1884,7 @@ Module::execPreprocessor(const char *infilename, llvm::raw_string_ostream *ostre
opts.addMacroDef("ISPC_MINOR_VERSION=3"); opts.addMacroDef("ISPC_MINOR_VERSION=3");
if (g->includeStdlib) { if (g->includeStdlib) {
if (g->opt.disableAsserts) if (g->opt.disableAsserts)
opts.addMacroDef("assert(x)="); opts.addMacroDef("assert(x)=");
else else
opts.addMacroDef("assert(x)=__assert(#x, x)"); opts.addMacroDef("assert(x)=__assert(#x, x)");
@@ -1944,7 +1944,7 @@ lGetTargetFileName(const char *outFileName, const char *isaString) {
// Given a comma-delimited string with one or more compilation targets of // Given a comma-delimited string with one or more compilation targets of
// the form "sse2,avx-x2", return a vector of strings where each returned // the form "sse2,avx-x2", return a vector of strings where each returned
// string holds one of the targets from the given string. // string holds one of the targets from the given string.
static std::vector<std::string> static std::vector<std::string>
lExtractTargets(const char *target) { lExtractTargets(const char *target) {
std::vector<std::string> targets; std::vector<std::string> targets;
const char *tstart = target; const char *tstart = target;
@@ -1985,14 +1985,14 @@ struct FunctionTargetVariants {
// Given the symbol table for a module, return a map from function names to // Given the symbol table for a module, return a map from function names to
// FunctionTargetVariants for each function that was defined with the // FunctionTargetVariants for each function that was defined with the
// 'export' qualifier in ispc. // 'export' qualifier in ispc.
static void static void
lGetExportedFunctions(SymbolTable *symbolTable, lGetExportedFunctions(SymbolTable *symbolTable,
std::map<std::string, FunctionTargetVariants> &functions) { std::map<std::string, FunctionTargetVariants> &functions) {
std::vector<Symbol *> syms; std::vector<Symbol *> syms;
symbolTable->GetMatchingFunctions(lSymbolIsExported, &syms); symbolTable->GetMatchingFunctions(lSymbolIsExported, &syms);
for (unsigned int i = 0; i < syms.size(); ++i) { for (unsigned int i = 0; i < syms.size(); ++i) {
FunctionTargetVariants &ftv = functions[syms[i]->name]; FunctionTargetVariants &ftv = functions[syms[i]->name];
ftv.func[g->target.isa] = syms[i]->exportedFunction; ftv.func[g->target.isa] = syms[i]->exportedFunction;
} }
} }
@@ -2016,7 +2016,7 @@ struct RewriteGlobalInfo {
// multiple definitions of them, one in each of the target-specific output // multiple definitions of them, one in each of the target-specific output
// files. // files.
static void static void
lExtractAndRewriteGlobals(llvm::Module *module, lExtractAndRewriteGlobals(llvm::Module *module,
std::vector<RewriteGlobalInfo> *globals) { std::vector<RewriteGlobalInfo> *globals) {
llvm::Module::global_iterator iter; llvm::Module::global_iterator iter;
for (iter = module->global_begin(); iter != module->global_end(); ++iter) { for (iter = module->global_begin(); iter != module->global_end(); ++iter) {
@@ -2029,7 +2029,7 @@ lExtractAndRewriteGlobals(llvm::Module *module,
llvm::Constant *init = gv->getInitializer(); llvm::Constant *init = gv->getInitializer();
gv->setInitializer(NULL); gv->setInitializer(NULL);
Symbol *sym = Symbol *sym =
m->symbolTable->LookupVariable(gv->getName().str().c_str()); m->symbolTable->LookupVariable(gv->getName().str().c_str());
Assert(sym != NULL); Assert(sym != NULL);
globals->push_back(RewriteGlobalInfo(gv, init, sym->pos)); globals->push_back(RewriteGlobalInfo(gv, init, sym->pos));
@@ -2067,7 +2067,7 @@ lAddExtractedGlobals(llvm::Module *module,
// Create a new global in the given model that matches the original // Create a new global in the given model that matches the original
// global // global
llvm::GlobalVariable *newGlobal = llvm::GlobalVariable *newGlobal =
new llvm::GlobalVariable(*module, type, gv->isConstant(), new llvm::GlobalVariable(*module, type, gv->isConstant(),
llvm::GlobalValue::ExternalLinkage, llvm::GlobalValue::ExternalLinkage,
initializer, gv->getName()); initializer, gv->getName());
@@ -2101,7 +2101,7 @@ lAddExtractedGlobals(llvm::Module *module,
/** Create the dispatch function for an exported ispc function. /** Create the dispatch function for an exported ispc function.
This function checks to see which vector ISAs the system the This function checks to see which vector ISAs the system the
code is running on supports and calls out to the best available code is running on supports and calls out to the best available
variant that was generated at compile time. variant that was generated at compile time.
@@ -2119,7 +2119,7 @@ lAddExtractedGlobals(llvm::Module *module,
*/ */
static void static void
lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc, lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
llvm::Value *systemBestISAPtr, const std::string &name, llvm::Value *systemBestISAPtr, const std::string &name,
FunctionTargetVariants &funcs) { FunctionTargetVariants &funcs) {
// The llvm::Function pointers in funcs are pointers to functions in // The llvm::Function pointers in funcs are pointers to functions in
// different llvm::Modules, so we can't call them directly. Therefore, // different llvm::Modules, so we can't call them directly. Therefore,
@@ -2144,18 +2144,18 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
if (ftype == NULL) if (ftype == NULL)
ftype = funcs.func[i]->getFunctionType(); ftype = funcs.func[i]->getFunctionType();
targetFuncs[i] = targetFuncs[i] =
llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage, llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage,
funcs.func[i]->getName(), module); funcs.func[i]->getName(), module);
} }
bool voidReturn = ftype->getReturnType()->isVoidTy(); bool voidReturn = ftype->getReturnType()->isVoidTy();
// Now we can emit the definition of the dispatch function.. // Now we can emit the definition of the dispatch function..
llvm::Function *dispatchFunc = llvm::Function *dispatchFunc =
llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage, llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage,
name.c_str(), module); name.c_str(), module);
llvm::BasicBlock *bblock = llvm::BasicBlock *bblock =
llvm::BasicBlock::Create(*g->ctx, "entry", dispatchFunc); llvm::BasicBlock::Create(*g->ctx, "entry", dispatchFunc);
// Start by calling out to the function that determines the system's // Start by calling out to the function that determines the system's
@@ -2163,7 +2163,7 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
llvm::CallInst::Create(setISAFunc, "", bblock); llvm::CallInst::Create(setISAFunc, "", bblock);
// Now we can load the system's ISA enuemrant // Now we can load the system's ISA enuemrant
llvm::Value *systemISA = llvm::Value *systemISA =
new llvm::LoadInst(systemBestISAPtr, "system_isa", bblock); new llvm::LoadInst(systemBestISAPtr, "system_isa", bblock);
// Now emit code that works backwards though the available variants of // Now emit code that works backwards though the available variants of
@@ -2179,12 +2179,12 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
// Emit code to see if the system can run the current candidate // Emit code to see if the system can run the current candidate
// variant successfully--"is the system's ISA enuemrant value >= // variant successfully--"is the system's ISA enuemrant value >=
// the enumerant value of the current candidate?" // the enumerant value of the current candidate?"
llvm::Value *ok = llvm::Value *ok =
llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGE, llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGE,
systemISA, LLVMInt32(i), "isa_ok", bblock); systemISA, LLVMInt32(i), "isa_ok", bblock);
llvm::BasicBlock *callBBlock = llvm::BasicBlock *callBBlock =
llvm::BasicBlock::Create(*g->ctx, "do_call", dispatchFunc); llvm::BasicBlock::Create(*g->ctx, "do_call", dispatchFunc);
llvm::BasicBlock *nextBBlock = llvm::BasicBlock *nextBBlock =
llvm::BasicBlock::Create(*g->ctx, "next_try", dispatchFunc); llvm::BasicBlock::Create(*g->ctx, "next_try", dispatchFunc);
llvm::BranchInst::Create(callBBlock, nextBBlock, ok, bblock); llvm::BranchInst::Create(callBBlock, nextBBlock, ok, bblock);
@@ -2192,7 +2192,7 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
// Just pass through all of the args from the dispatch function to // Just pass through all of the args from the dispatch function to
// the target-specific function. // the target-specific function.
std::vector<llvm::Value *> args; std::vector<llvm::Value *> args;
llvm::Function::arg_iterator argIter = dispatchFunc->arg_begin(); llvm::Function::arg_iterator argIter = dispatchFunc->arg_begin();
for (; argIter != dispatchFunc->arg_end(); ++argIter) for (; argIter != dispatchFunc->arg_end(); ++argIter)
args.push_back(argIter); args.push_back(argIter);
if (voidReturn) { if (voidReturn) {
@@ -2200,8 +2200,8 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
llvm::ReturnInst::Create(*g->ctx, callBBlock); llvm::ReturnInst::Create(*g->ctx, callBBlock);
} }
else { else {
llvm::Value *retValue = llvm::Value *retValue =
llvm::CallInst::Create(targetFuncs[i], args, "ret_value", llvm::CallInst::Create(targetFuncs[i], args, "ret_value",
callBBlock); callBBlock);
llvm::ReturnInst::Create(*g->ctx, retValue, callBBlock); llvm::ReturnInst::Create(*g->ctx, retValue, callBBlock);
} }
@@ -2244,13 +2244,13 @@ lCreateDispatchModule(std::map<std::string, FunctionTargetVariants> &functions)
// First, link in the definitions from the builtins-dispatch.ll file. // First, link in the definitions from the builtins-dispatch.ll file.
extern unsigned char builtins_bitcode_dispatch[]; extern unsigned char builtins_bitcode_dispatch[];
extern int builtins_bitcode_dispatch_length; extern int builtins_bitcode_dispatch_length;
AddBitcodeToModule(builtins_bitcode_dispatch, AddBitcodeToModule(builtins_bitcode_dispatch,
builtins_bitcode_dispatch_length, module); builtins_bitcode_dispatch_length, module);
// Get pointers to things we need below // Get pointers to things we need below
llvm::Function *setFunc = module->getFunction("__set_system_isa"); llvm::Function *setFunc = module->getFunction("__set_system_isa");
Assert(setFunc != NULL); Assert(setFunc != NULL);
llvm::Value *systemBestISAPtr = llvm::Value *systemBestISAPtr =
module->getGlobalVariable("__system_best_isa", true); module->getGlobalVariable("__system_best_isa", true);
Assert(systemBestISAPtr != NULL); Assert(systemBestISAPtr != NULL);
@@ -2272,18 +2272,18 @@ lCreateDispatchModule(std::map<std::string, FunctionTargetVariants> &functions)
int int
Module::CompileAndOutput(const char *srcFile, Module::CompileAndOutput(const char *srcFile,
const char *arch, const char *arch,
const char *cpu, const char *cpu,
const char *target, const char *target,
bool generatePIC, bool generatePIC,
OutputType outputType, OutputType outputType,
const char *outFileName, const char *outFileName,
const char *headerFileName, const char *headerFileName,
const char *includeFileName, const char *includeFileName,
const char *depsFileName, const char *depsFileName,
const char *hostStubFileName, const char *hostStubFileName,
const char *devStubFileName) const char *devStubFileName)
{ {
if (target == NULL || strchr(target, ',') == NULL) { if (target == NULL || strchr(target, ',') == NULL) {
// We're only compiling to a single target // We're only compiling to a single target
@@ -2368,7 +2368,7 @@ Module::CompileAndOutput(const char *srcFile,
std::vector<RewriteGlobalInfo> globals[Target::NUM_ISAS]; std::vector<RewriteGlobalInfo> globals[Target::NUM_ISAS];
int errorCount = 0; int errorCount = 0;
for (unsigned int i = 0; i < targets.size(); ++i) { for (unsigned int i = 0; i < targets.size(); ++i) {
if (!Target::GetTarget(arch, cpu, targets[i].c_str(), generatePIC, if (!Target::GetTarget(arch, cpu, targets[i].c_str(), generatePIC,
&g->target)) &g->target))
return 1; return 1;
@@ -2393,7 +2393,7 @@ Module::CompileAndOutput(const char *srcFile,
if (outFileName != NULL) { if (outFileName != NULL) {
const char *isaName = g->target.GetISAString(); const char *isaName = g->target.GetISAString();
std::string targetOutFileName = std::string targetOutFileName =
lGetTargetFileName(outFileName, isaName); lGetTargetFileName(outFileName, isaName);
if (!m->writeOutput(outputType, targetOutFileName.c_str())) if (!m->writeOutput(outputType, targetOutFileName.c_str()))
return 1; return 1;
@@ -2412,7 +2412,7 @@ Module::CompileAndOutput(const char *srcFile,
// we generate the dispatch module's functions... // we generate the dispatch module's functions...
} }
llvm::Module *dispatchModule = llvm::Module *dispatchModule =
lCreateDispatchModule(exportedFunctions); lCreateDispatchModule(exportedFunctions);
lAddExtractedGlobals(dispatchModule, globals); lAddExtractedGlobals(dispatchModule, globals);
@@ -2434,7 +2434,7 @@ Module::CompileAndOutput(const char *srcFile,
writeObjectFileOrAssembly(firstTargetMachine, dispatchModule, writeObjectFileOrAssembly(firstTargetMachine, dispatchModule,
outputType, outFileName); outputType, outFileName);
} }
return errorCount > 0; return errorCount > 0;
} }
} }

View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file module.h /** @file module.h
@@ -64,7 +64,7 @@ public:
/** Add a new global variable corresponding to the given Symbol to the /** Add a new global variable corresponding to the given Symbol to the
module. If non-NULL, initExpr gives the initiailizer expression module. If non-NULL, initExpr gives the initiailizer expression
for the global's inital value. */ for the global's inital value. */
void AddGlobalVariable(const std::string &name, const Type *type, void AddGlobalVariable(const std::string &name, const Type *type,
Expr *initExpr, bool isConst, Expr *initExpr, bool isConst,
StorageClass storageClass, SourcePos pos); StorageClass storageClass, SourcePos pos);
@@ -72,7 +72,7 @@ public:
/** Add a declaration of the function defined by the given function /** Add a declaration of the function defined by the given function
symbol to the module. */ symbol to the module. */
void AddFunctionDeclaration(const std::string &name, void AddFunctionDeclaration(const std::string &name,
const FunctionType *ftype, const FunctionType *ftype,
StorageClass sc, bool isInline, SourcePos pos); StorageClass sc, bool isInline, SourcePos pos);
/** Adds the function described by the declaration information and the /** Adds the function described by the declaration information and the
@@ -82,7 +82,7 @@ public:
/** Adds the given type to the set of types that have their definitions /** Adds the given type to the set of types that have their definitions
included in automatically generated header files. */ included in automatically generated header files. */
void AddExportedTypes(const std::vector<std::pair<const Type *, void AddExportedTypes(const std::vector<std::pair<const Type *,
SourcePos> > &types); SourcePos> > &types);
/** After a source file has been compiled, output can be generated in a /** After a source file has been compiled, output can be generated in a
@@ -91,7 +91,7 @@ public:
Bitcode, /** Generate LLVM IR bitcode output */ Bitcode, /** Generate LLVM IR bitcode output */
Object, /** Generate a native object file */ Object, /** Generate a native object file */
CXX, /** Generate a C++ file */ CXX, /** Generate a C++ file */
Header, /** Generate a C/C++ header file with Header, /** Generate a C/C++ header file with
declarations of 'export'ed functions, global declarations of 'export'ed functions, global
variables, and the types used by them. */ variables, and the types used by them. */
Deps, /** generate dependencies */ Deps, /** generate dependencies */
@@ -104,14 +104,14 @@ public:
declarations of functions and types used in the ispc/application declarations of functions and types used in the ispc/application
interface. interface.
@param srcFile Pathname to ispc source file to compile @param srcFile Pathname to ispc source file to compile
@param arch Target architecture (e.g. "x86-64") @param arch %Target architecture (e.g. "x86-64")
@param cpu Target CPU (e.g. "core-i7") @param cpu %Target CPU (e.g. "core-i7")
@param targets Target ISAs; this parameter may give a single target @param targets %Target ISAs; this parameter may give a single target
ISA, or may give a comma-separated list of them in ISA, or may give a comma-separated list of them in
case we are compiling to multiple ISAs. case we are compiling to multiple ISAs.
@param generatePIC Indicates whether position-independent code should @param generatePIC Indicates whether position-independent code should
be generated. be generated.
@param outputType Type of output to generate (object files, assembly, @param outputType %Type of output to generate (object files, assembly,
LLVM bitcode.) LLVM bitcode.)
@param outFileName Base name of output filename for object files, etc. @param outFileName Base name of output filename for object files, etc.
If for example the multiple targets "sse2" and "avx" If for example the multiple targets "sse2" and "avx"
@@ -122,18 +122,18 @@ public:
inclusion from C/C++ code with declarations of inclusion from C/C++ code with declarations of
types and functions exported from the given ispc types and functions exported from the given ispc
source file. source file.
@param includeFileName If non-NULL, gives the filename for the C++ @param includeFileName If non-NULL, gives the filename for the C++
backend to emit in an #include statement to backend to emit in an #include statement to
get definitions of the builtins for the generic get definitions of the builtins for the generic
target. target.
@return Number of errors encountered when compiling @return Number of errors encountered when compiling
srcFile. srcFile.
*/ */
static int CompileAndOutput(const char *srcFile, const char *arch, static int CompileAndOutput(const char *srcFile, const char *arch,
const char *cpu, const char *targets, const char *cpu, const char *targets,
bool generatePIC, bool generatePIC,
OutputType outputType, OutputType outputType,
const char *outFileName, const char *outFileName,
const char *headerFileName, const char *headerFileName,
const char *includeFileName, const char *includeFileName,
const char *depsFileName, const char *depsFileName,
@@ -148,7 +148,7 @@ public:
SymbolTable *symbolTable; SymbolTable *symbolTable;
/** llvm Module object into which globals and functions are added. */ /** llvm Module object into which globals and functions are added. */
llvm::Module *module; llvm::Module *module;
/** The diBuilder manages generating debugging information */ /** The diBuilder manages generating debugging information */
llvm::DIBuilder *diBuilder; llvm::DIBuilder *diBuilder;
@@ -171,7 +171,7 @@ private:
bool writeHostStub(const char *filename); bool writeHostStub(const char *filename);
bool writeObjectFileOrAssembly(OutputType outputType, const char *filename); bool writeObjectFileOrAssembly(OutputType outputType, const char *filename);
static bool writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine, static bool writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
llvm::Module *module, OutputType outputType, llvm::Module *module, OutputType outputType,
const char *outFileName); const char *outFileName);
static bool writeBitcode(llvm::Module *module, const char *outFileName); static bool writeBitcode(llvm::Module *module, const char *outFileName);

582
opt.cpp

File diff suppressed because it is too large Load Diff

4
opt.h
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file opt.h /** @file opt.h
@@ -43,7 +43,7 @@
/** Optimize the functions in the given module, applying the specified /** Optimize the functions in the given module, applying the specified
level of optimization. optLevel zero corresponds to essentially no level of optimization. optLevel zero corresponds to essentially no
optimization--just enough to generate correct code, while level one optimization--just enough to generate correct code, while level one
corresponds to full optimization. corresponds to full optimization.
*/ */
void Optimize(llvm::Module *module, int optLevel); void Optimize(llvm::Module *module, int optLevel);

228
parse.yy
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
%locations %locations
@@ -125,14 +125,14 @@ static const char *lBuiltinTokens[] = {
"foreach_unique", "goto", "if", "in", "inline", "foreach_unique", "goto", "if", "in", "inline",
"int", "int8", "int16", "int32", "int64", "launch", "new", "NULL", "int", "int8", "int16", "int32", "int64", "launch", "new", "NULL",
"print", "return", "signed", "sizeof", "static", "struct", "switch", "print", "return", "signed", "sizeof", "static", "struct", "switch",
"sync", "task", "true", "typedef", "uniform", "unmasked", "unsigned", "sync", "task", "true", "typedef", "uniform", "unmasked", "unsigned",
"varying", "void", "while", NULL "varying", "void", "while", NULL
}; };
static const char *lParamListTokens[] = { static const char *lParamListTokens[] = {
"bool", "const", "double", "enum", "false", "float", "int", "bool", "const", "double", "enum", "false", "float", "int",
"int8", "int16", "int32", "int64", "signed", "struct", "true", "int8", "int16", "int32", "int64", "signed", "struct", "true",
"uniform", "unsigned", "varying", "void", NULL "uniform", "unsigned", "varying", "void", NULL
}; };
struct ForeachDimension { struct ForeachDimension {
@@ -179,27 +179,27 @@ struct ForeachDimension {
} }
%token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT %token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT
%token TOKEN_INT64_CONSTANT TOKEN_UINT64_CONSTANT %token TOKEN_INT64_CONSTANT TOKEN_UINT64_CONSTANT
%token TOKEN_INT32DOTDOTDOT_CONSTANT TOKEN_UINT32DOTDOTDOT_CONSTANT %token TOKEN_INT32DOTDOTDOT_CONSTANT TOKEN_UINT32DOTDOTDOT_CONSTANT
%token TOKEN_INT64DOTDOTDOT_CONSTANT TOKEN_UINT64DOTDOTDOT_CONSTANT %token TOKEN_INT64DOTDOTDOT_CONSTANT TOKEN_UINT64DOTDOTDOT_CONSTANT
%token TOKEN_FLOAT_CONSTANT TOKEN_STRING_C_LITERAL %token TOKEN_FLOAT_CONSTANT TOKEN_STRING_C_LITERAL
%token TOKEN_IDENTIFIER TOKEN_STRING_LITERAL TOKEN_TYPE_NAME TOKEN_NULL %token TOKEN_IDENTIFIER TOKEN_STRING_LITERAL TOKEN_TYPE_NAME TOKEN_NULL
%token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP %token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP
%token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP %token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP
%token TOKEN_AND_OP TOKEN_OR_OP TOKEN_MUL_ASSIGN TOKEN_DIV_ASSIGN TOKEN_MOD_ASSIGN %token TOKEN_AND_OP TOKEN_OR_OP TOKEN_MUL_ASSIGN TOKEN_DIV_ASSIGN TOKEN_MOD_ASSIGN
%token TOKEN_ADD_ASSIGN TOKEN_SUB_ASSIGN TOKEN_LEFT_ASSIGN TOKEN_RIGHT_ASSIGN %token TOKEN_ADD_ASSIGN TOKEN_SUB_ASSIGN TOKEN_LEFT_ASSIGN TOKEN_RIGHT_ASSIGN
%token TOKEN_AND_ASSIGN TOKEN_OR_ASSIGN TOKEN_XOR_ASSIGN %token TOKEN_AND_ASSIGN TOKEN_OR_ASSIGN TOKEN_XOR_ASSIGN
%token TOKEN_SIZEOF TOKEN_NEW TOKEN_DELETE TOKEN_IN %token TOKEN_SIZEOF TOKEN_NEW TOKEN_DELETE TOKEN_IN
%token TOKEN_EXTERN TOKEN_EXPORT TOKEN_STATIC TOKEN_INLINE TOKEN_TASK TOKEN_DECLSPEC %token TOKEN_EXTERN TOKEN_EXPORT TOKEN_STATIC TOKEN_INLINE TOKEN_TASK TOKEN_DECLSPEC
%token TOKEN_UNIFORM TOKEN_VARYING TOKEN_TYPEDEF TOKEN_SOA TOKEN_UNMASKED %token TOKEN_UNIFORM TOKEN_VARYING TOKEN_TYPEDEF TOKEN_SOA TOKEN_UNMASKED
%token TOKEN_CHAR TOKEN_INT TOKEN_SIGNED TOKEN_UNSIGNED TOKEN_FLOAT TOKEN_DOUBLE %token TOKEN_CHAR TOKEN_INT TOKEN_SIGNED TOKEN_UNSIGNED TOKEN_FLOAT TOKEN_DOUBLE
%token TOKEN_INT8 TOKEN_INT16 TOKEN_INT64 TOKEN_CONST TOKEN_VOID TOKEN_BOOL %token TOKEN_INT8 TOKEN_INT16 TOKEN_INT64 TOKEN_CONST TOKEN_VOID TOKEN_BOOL
%token TOKEN_ENUM TOKEN_STRUCT TOKEN_TRUE TOKEN_FALSE %token TOKEN_ENUM TOKEN_STRUCT TOKEN_TRUE TOKEN_FALSE
%token TOKEN_CASE TOKEN_DEFAULT TOKEN_IF TOKEN_ELSE TOKEN_SWITCH %token TOKEN_CASE TOKEN_DEFAULT TOKEN_IF TOKEN_ELSE TOKEN_SWITCH
%token TOKEN_WHILE TOKEN_DO TOKEN_LAUNCH TOKEN_FOREACH TOKEN_FOREACH_TILED %token TOKEN_WHILE TOKEN_DO TOKEN_LAUNCH TOKEN_FOREACH TOKEN_FOREACH_TILED
%token TOKEN_FOREACH_UNIQUE TOKEN_FOREACH_ACTIVE TOKEN_DOTDOTDOT %token TOKEN_FOREACH_UNIQUE TOKEN_FOREACH_ACTIVE TOKEN_DOTDOTDOT
%token TOKEN_FOR TOKEN_GOTO TOKEN_CONTINUE TOKEN_BREAK TOKEN_RETURN %token TOKEN_FOR TOKEN_GOTO TOKEN_CONTINUE TOKEN_BREAK TOKEN_RETURN
%token TOKEN_CIF TOKEN_CDO TOKEN_CFOR TOKEN_CWHILE %token TOKEN_CIF TOKEN_CDO TOKEN_CFOR TOKEN_CWHILE
@@ -221,7 +221,7 @@ struct ForeachDimension {
%type <stmt> assert_statement sync_statement delete_statement unmasked_statement %type <stmt> assert_statement sync_statement delete_statement unmasked_statement
%type <declaration> declaration parameter_declaration %type <declaration> declaration parameter_declaration
%type <declarators> init_declarator_list %type <declarators> init_declarator_list
%type <declarationList> parameter_list parameter_type_list %type <declarationList> parameter_list parameter_type_list
%type <declarator> declarator pointer reference %type <declarator> declarator pointer reference
%type <declarator> init_declarator direct_declarator struct_declarator %type <declarator> init_declarator direct_declarator struct_declarator
@@ -244,10 +244,10 @@ struct ForeachDimension {
%type <typeQualifier> type_qualifier type_qualifier_list %type <typeQualifier> type_qualifier type_qualifier_list
%type <storageClass> storage_class_specifier %type <storageClass> storage_class_specifier
%type <declSpecs> declaration_specifiers %type <declSpecs> declaration_specifiers
%type <stringVal> string_constant %type <stringVal> string_constant
%type <constCharPtr> struct_or_union_name enum_identifier goto_identifier %type <constCharPtr> struct_or_union_name enum_identifier goto_identifier
%type <constCharPtr> foreach_unique_identifier %type <constCharPtr> foreach_unique_identifier
%type <intVal> int_constant soa_width_specifier rate_qualified_new %type <intVal> int_constant soa_width_specifier rate_qualified_new
@@ -277,7 +277,7 @@ primary_expression
Symbol *s = m->symbolTable->LookupVariable(name); Symbol *s = m->symbolTable->LookupVariable(name);
$$ = NULL; $$ = NULL;
if (s) if (s)
$$ = new SymbolExpr(s, @1); $$ = new SymbolExpr(s, @1);
else { else {
std::vector<Symbol *> funs; std::vector<Symbol *> funs;
m->symbolTable->LookupFunction(name, &funs); m->symbolTable->LookupFunction(name, &funs);
@@ -285,7 +285,7 @@ primary_expression
$$ = new FunctionSymbolExpr(name, funs, @1); $$ = new FunctionSymbolExpr(name, funs, @1);
} }
if ($$ == NULL) { if ($$ == NULL) {
std::vector<std::string> alternates = std::vector<std::string> alternates =
m->symbolTable->ClosestVariableOrFunctionMatch(name); m->symbolTable->ClosestVariableOrFunctionMatch(name);
std::string alts = lGetAlternates(alternates); std::string alts = lGetAlternates(alternates);
Error(@1, "Undeclared symbol \"%s\".%s", name, alts.c_str()); Error(@1, "Undeclared symbol \"%s\".%s", name, alts.c_str());
@@ -293,23 +293,23 @@ primary_expression
} }
| TOKEN_INT32_CONSTANT { | TOKEN_INT32_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(), $$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
(int32_t)yylval.intVal, @1); (int32_t)yylval.intVal, @1);
} }
| TOKEN_UINT32_CONSTANT { | TOKEN_UINT32_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(), $$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
(uint32_t)yylval.intVal, @1); (uint32_t)yylval.intVal, @1);
} }
| TOKEN_INT64_CONSTANT { | TOKEN_INT64_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(), $$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
(int64_t)yylval.intVal, @1); (int64_t)yylval.intVal, @1);
} }
| TOKEN_UINT64_CONSTANT { | TOKEN_UINT64_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(), $$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
(uint64_t)yylval.intVal, @1); (uint64_t)yylval.intVal, @1);
} }
| TOKEN_FLOAT_CONSTANT { | TOKEN_FLOAT_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformFloat->GetAsConstType(), $$ = new ConstExpr(AtomicType::UniformFloat->GetAsConstType(),
(float)yylval.floatVal, @1); (float)yylval.floatVal, @1);
} }
| TOKEN_TRUE { | TOKEN_TRUE {
$$ = new ConstExpr(AtomicType::UniformBool->GetAsConstType(), true, @1); $$ = new ConstExpr(AtomicType::UniformBool->GetAsConstType(), true, @1);
@@ -328,7 +328,7 @@ primary_expression
launch_expression launch_expression
: TOKEN_LAUNCH postfix_expression '(' argument_expression_list ')' : TOKEN_LAUNCH postfix_expression '(' argument_expression_list ')'
{ {
ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @2); ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @2);
$$ = new FunctionCallExpr($2, $4, Union(@2, @5), true, oneExpr); $$ = new FunctionCallExpr($2, $4, Union(@2, @5), true, oneExpr);
} }
@@ -343,7 +343,7 @@ launch_expression
{ $$ = new FunctionCallExpr($5, new ExprList(Union(@5,@6)), Union(@5,@7), true, $3); } { $$ = new FunctionCallExpr($5, new ExprList(Union(@5,@6)), Union(@5,@7), true, $3); }
| TOKEN_LAUNCH '<' postfix_expression '(' argument_expression_list ')' '>' | TOKEN_LAUNCH '<' postfix_expression '(' argument_expression_list ')' '>'
{ {
Error(Union(@2, @7), "\"launch\" expressions no longer take '<' '>' " Error(Union(@2, @7), "\"launch\" expressions no longer take '<' '>' "
"around function call expression."); "around function call expression.");
$$ = NULL; $$ = NULL;
@@ -412,21 +412,21 @@ argument_expression_list
unary_expression unary_expression
: funcall_expression : funcall_expression
| TOKEN_INC_OP unary_expression | TOKEN_INC_OP unary_expression
{ $$ = new UnaryExpr(UnaryExpr::PreInc, $2, Union(@1, @2)); } { $$ = new UnaryExpr(UnaryExpr::PreInc, $2, Union(@1, @2)); }
| TOKEN_DEC_OP unary_expression | TOKEN_DEC_OP unary_expression
{ $$ = new UnaryExpr(UnaryExpr::PreDec, $2, Union(@1, @2)); } { $$ = new UnaryExpr(UnaryExpr::PreDec, $2, Union(@1, @2)); }
| '&' unary_expression | '&' unary_expression
{ $$ = new AddressOfExpr($2, Union(@1, @2)); } { $$ = new AddressOfExpr($2, Union(@1, @2)); }
| '*' unary_expression | '*' unary_expression
{ $$ = new PtrDerefExpr($2, Union(@1, @2)); } { $$ = new PtrDerefExpr($2, Union(@1, @2)); }
| '+' cast_expression | '+' cast_expression
{ $$ = $2; } { $$ = $2; }
| '-' cast_expression | '-' cast_expression
{ $$ = new UnaryExpr(UnaryExpr::Negate, $2, Union(@1, @2)); } { $$ = new UnaryExpr(UnaryExpr::Negate, $2, Union(@1, @2)); }
| '~' cast_expression | '~' cast_expression
{ $$ = new UnaryExpr(UnaryExpr::BitNot, $2, Union(@1, @2)); } { $$ = new UnaryExpr(UnaryExpr::BitNot, $2, Union(@1, @2)); }
| '!' cast_expression | '!' cast_expression
{ $$ = new UnaryExpr(UnaryExpr::LogicalNot, $2, Union(@1, @2)); } { $$ = new UnaryExpr(UnaryExpr::LogicalNot, $2, Union(@1, @2)); }
| TOKEN_SIZEOF unary_expression | TOKEN_SIZEOF unary_expression
{ $$ = new SizeOfExpr($2, Union(@1, @2)); } { $$ = new SizeOfExpr($2, Union(@1, @2)); }
@@ -438,7 +438,7 @@ cast_expression
: unary_expression : unary_expression
| '(' type_name ')' cast_expression | '(' type_name ')' cast_expression
{ {
$$ = new TypeCastExpr($2, $4, Union(@1,@4)); $$ = new TypeCastExpr($2, $4, Union(@1,@4));
} }
; ;
@@ -630,7 +630,7 @@ constant_expression
; ;
declaration_statement declaration_statement
: declaration : declaration
{ {
if ($1 == NULL) { if ($1 == NULL) {
AssertPos(@1, m->errorCount > 0); AssertPos(@1, m->errorCount > 0);
@@ -810,11 +810,11 @@ init_declarator_list
init_declarator init_declarator
: declarator : declarator
| declarator '=' initializer | declarator '=' initializer
{ {
if ($1 != NULL) if ($1 != NULL)
$1->initExpr = $3; $1->initExpr = $3;
$$ = $1; $$ = $1;
} }
; ;
@@ -829,7 +829,7 @@ type_specifier
: atomic_var_type_specifier { $$ = $1; } : atomic_var_type_specifier { $$ = $1; }
| TOKEN_TYPE_NAME | TOKEN_TYPE_NAME
{ {
const Type *t = m->symbolTable->LookupType(yytext); const Type *t = m->symbolTable->LookupType(yytext);
$$ = t; $$ = t;
} }
| struct_or_union_specifier { $$ = $1; } | struct_or_union_specifier { $$ = $1; }
@@ -837,7 +837,7 @@ type_specifier
; ;
type_specifier_list type_specifier_list
: type_specifier : type_specifier
{ {
if ($1 == NULL) if ($1 == NULL)
$$ = NULL; $$ = NULL;
@@ -883,8 +883,8 @@ struct_or_union_name
struct_or_union_and_name struct_or_union_and_name
: struct_or_union struct_or_union_name : struct_or_union struct_or_union_name
{ {
const Type *st = m->symbolTable->LookupType($2); const Type *st = m->symbolTable->LookupType($2);
if (st == NULL) { if (st == NULL) {
st = new UndefinedStructType($2, Variability::Unbound, false, @2); st = new UndefinedStructType($2, Variability::Unbound, false, @2);
m->symbolTable->AddType($2, st, @2); m->symbolTable->AddType($2, st, @2);
@@ -905,7 +905,7 @@ struct_or_union_and_name
struct_or_union_specifier struct_or_union_specifier
: struct_or_union_and_name : struct_or_union_and_name
| struct_or_union_and_name '{' struct_declaration_list '}' | struct_or_union_and_name '{' struct_declaration_list '}'
{ {
if ($3 != NULL) { if ($3 != NULL) {
llvm::SmallVector<const Type *, 8> elementTypes; llvm::SmallVector<const Type *, 8> elementTypes;
@@ -924,7 +924,7 @@ struct_or_union_specifier
else else
$$ = NULL; $$ = NULL;
} }
| struct_or_union '{' struct_declaration_list '}' | struct_or_union '{' struct_declaration_list '}'
{ {
if ($3 != NULL) { if ($3 != NULL) {
llvm::SmallVector<const Type *, 8> elementTypes; llvm::SmallVector<const Type *, 8> elementTypes;
@@ -938,7 +938,7 @@ struct_or_union_specifier
else else
$$ = NULL; $$ = NULL;
} }
| struct_or_union '{' '}' | struct_or_union '{' '}'
{ {
llvm::SmallVector<const Type *, 8> elementTypes; llvm::SmallVector<const Type *, 8> elementTypes;
llvm::SmallVector<std::string, 8> elementNames; llvm::SmallVector<std::string, 8> elementNames;
@@ -946,7 +946,7 @@ struct_or_union_specifier
$$ = new StructType("", elementTypes, elementNames, elementPositions, $$ = new StructType("", elementTypes, elementNames, elementPositions,
false, Variability::Unbound, @1); false, Variability::Unbound, @1);
} }
| struct_or_union_and_name '{' '}' | struct_or_union_and_name '{' '}'
{ {
llvm::SmallVector<const Type *, 8> elementTypes; llvm::SmallVector<const Type *, 8> elementTypes;
llvm::SmallVector<std::string, 8> elementNames; llvm::SmallVector<std::string, 8> elementNames;
@@ -963,18 +963,18 @@ struct_or_union_specifier
; ;
struct_or_union struct_or_union
: TOKEN_STRUCT : TOKEN_STRUCT
; ;
struct_declaration_list struct_declaration_list
: struct_declaration : struct_declaration
{ {
std::vector<StructDeclaration *> *sdl = new std::vector<StructDeclaration *>; std::vector<StructDeclaration *> *sdl = new std::vector<StructDeclaration *>;
if ($1 != NULL) if ($1 != NULL)
sdl->push_back($1); sdl->push_back($1);
$$ = sdl; $$ = sdl;
} }
| struct_declaration_list struct_declaration | struct_declaration_list struct_declaration
{ {
std::vector<StructDeclaration *> *sdl = (std::vector<StructDeclaration *> *)$1; std::vector<StructDeclaration *> *sdl = (std::vector<StructDeclaration *> *)$1;
if (sdl == NULL) { if (sdl == NULL) {
@@ -988,7 +988,7 @@ struct_declaration_list
; ;
struct_declaration struct_declaration
: specifier_qualifier_list struct_declarator_list ';' : specifier_qualifier_list struct_declarator_list ';'
{ $$ = ($1 != NULL && $2 != NULL) ? new StructDeclaration($1, $2) : NULL; } { $$ = ($1 != NULL && $2 != NULL) ? new StructDeclaration($1, $2) : NULL; }
; ;
@@ -996,7 +996,7 @@ specifier_qualifier_list
: type_specifier specifier_qualifier_list : type_specifier specifier_qualifier_list
| type_specifier | type_specifier
| short_vec_specifier | short_vec_specifier
| type_qualifier specifier_qualifier_list | type_qualifier specifier_qualifier_list
{ {
if ($2 != NULL) { if ($2 != NULL) {
if ($1 == TYPEQUAL_UNIFORM) { if ($1 == TYPEQUAL_UNIFORM) {
@@ -1033,7 +1033,7 @@ specifier_qualifier_list
$2->ResolveUnboundVariability(Variability::Varying)->GetString().c_str()); $2->ResolveUnboundVariability(Variability::Varying)->GetString().c_str());
$$ = $2; $$ = $2;
} }
} }
else if ($1 == TYPEQUAL_INLINE) { else if ($1 == TYPEQUAL_INLINE) {
Error(@1, "\"inline\" qualifier is illegal outside of " Error(@1, "\"inline\" qualifier is illegal outside of "
"function declarations."); "function declarations.");
@@ -1059,7 +1059,7 @@ specifier_qualifier_list
} }
else { else {
if (m->errorCount == 0) if (m->errorCount == 0)
Error(@1, "Lost type qualifier in parser."); Error(@1, "Lost type qualifier in parser.");
$$ = NULL; $$ = NULL;
} }
} }
@@ -1067,14 +1067,14 @@ specifier_qualifier_list
struct_declarator_list struct_declarator_list
: struct_declarator : struct_declarator
{ {
std::vector<Declarator *> *sdl = new std::vector<Declarator *>; std::vector<Declarator *> *sdl = new std::vector<Declarator *>;
if ($1 != NULL) if ($1 != NULL)
sdl->push_back($1); sdl->push_back($1);
$$ = sdl; $$ = sdl;
} }
| struct_declarator_list ',' struct_declarator | struct_declarator_list ',' struct_declarator
{ {
std::vector<Declarator *> *sdl = (std::vector<Declarator *> *)$1; std::vector<Declarator *> *sdl = (std::vector<Declarator *> *)$1;
if (sdl == NULL) { if (sdl == NULL) {
@@ -1099,19 +1099,19 @@ enum_identifier
: TOKEN_IDENTIFIER { $$ = strdup(yytext); } : TOKEN_IDENTIFIER { $$ = strdup(yytext); }
enum_specifier enum_specifier
: TOKEN_ENUM '{' enumerator_list '}' : TOKEN_ENUM '{' enumerator_list '}'
{ {
$$ = lCreateEnumType(NULL, $3, @1); $$ = lCreateEnumType(NULL, $3, @1);
} }
| TOKEN_ENUM enum_identifier '{' enumerator_list '}' | TOKEN_ENUM enum_identifier '{' enumerator_list '}'
{ {
$$ = lCreateEnumType($2, $4, @2); $$ = lCreateEnumType($2, $4, @2);
} }
| TOKEN_ENUM '{' enumerator_list ',' '}' | TOKEN_ENUM '{' enumerator_list ',' '}'
{ {
$$ = lCreateEnumType(NULL, $3, @1); $$ = lCreateEnumType(NULL, $3, @1);
} }
| TOKEN_ENUM enum_identifier '{' enumerator_list ',' '}' | TOKEN_ENUM enum_identifier '{' enumerator_list ',' '}'
{ {
$$ = lCreateEnumType($2, $4, @2); $$ = lCreateEnumType($2, $4, @2);
} }
@@ -1138,12 +1138,12 @@ enum_specifier
; ;
enumerator_list enumerator_list
: enumerator : enumerator
{ {
if ($1 == NULL) if ($1 == NULL)
$$ = NULL; $$ = NULL;
else { else {
std::vector<Symbol *> *el = new std::vector<Symbol *>; std::vector<Symbol *> *el = new std::vector<Symbol *>;
el->push_back($1); el->push_back($1);
$$ = el; $$ = el;
} }
@@ -1198,7 +1198,7 @@ type_qualifier_list
{ {
$$ = $1; $$ = $1;
} }
| type_qualifier_list type_qualifier | type_qualifier_list type_qualifier
{ {
$$ = $1 | $2; $$ = $1 | $2;
} }
@@ -1243,9 +1243,9 @@ direct_declarator
d->name = yytext; d->name = yytext;
$$ = d; $$ = d;
} }
| '(' declarator ')' | '(' declarator ')'
{ {
$$ = $2; $$ = $2;
} }
| direct_declarator '[' constant_expression ']' | direct_declarator '[' constant_expression ']'
{ {
@@ -1310,9 +1310,9 @@ direct_declarator
pointer pointer
: '*' : '*'
{ {
$$ = new Declarator(DK_POINTER, @1); $$ = new Declarator(DK_POINTER, @1);
} }
| '*' type_qualifier_list | '*' type_qualifier_list
{ {
@@ -1337,9 +1337,9 @@ pointer
reference reference
: '&' : '&'
{ {
$$ = new Declarator(DK_REFERENCE, @1); $$ = new Declarator(DK_REFERENCE, @1);
} }
; ;
@@ -1375,10 +1375,10 @@ parameter_list
parameter_declaration parameter_declaration
: declaration_specifiers declarator : declaration_specifiers declarator
{ {
$$ = new Declaration($1, $2); $$ = new Declaration($1, $2);
} }
| declaration_specifiers declarator '=' initializer | declaration_specifiers declarator '=' initializer
{ {
if ($1 != NULL && $2 != NULL) { if ($1 != NULL && $2 != NULL) {
$2->initExpr = $4; $2->initExpr = $4;
$$ = new Declaration($1, $2); $$ = new Declaration($1, $2);
@@ -1398,11 +1398,11 @@ parameter_declaration
if ($1 == NULL) if ($1 == NULL)
$$ = NULL; $$ = NULL;
else else
$$ = new Declaration($1); $$ = new Declaration($1);
} }
; ;
/* K&R? /* K&R?
identifier_list identifier_list
: IDENTIFIER : IDENTIFIER
| identifier_list ',' IDENTIFIER | identifier_list ',' IDENTIFIER
@@ -1588,9 +1588,9 @@ labeled_statement
$$ = new LabeledStmt($1, $3, @1); $$ = new LabeledStmt($1, $3, @1);
} }
| TOKEN_CASE constant_expression ':' statement | TOKEN_CASE constant_expression ':' statement
{ {
int value; int value;
if ($2 != NULL && if ($2 != NULL &&
lGetConstantInt($2, &value, @2, "Case statement value")) { lGetConstantInt($2, &value, @2, "Case statement value")) {
$$ = new CaseStmt(value, $4, Union(@1, @2)); $$ = new CaseStmt(value, $4, Union(@1, @2));
} }
@@ -1700,19 +1700,19 @@ foreach_active_identifier
integer_dotdotdot integer_dotdotdot
: TOKEN_INT32DOTDOTDOT_CONSTANT { : TOKEN_INT32DOTDOTDOT_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(), $$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
(int32_t)yylval.intVal, @1); (int32_t)yylval.intVal, @1);
} }
| TOKEN_UINT32DOTDOTDOT_CONSTANT { | TOKEN_UINT32DOTDOTDOT_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(), $$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
(uint32_t)yylval.intVal, @1); (uint32_t)yylval.intVal, @1);
} }
| TOKEN_INT64DOTDOTDOT_CONSTANT { | TOKEN_INT64DOTDOTDOT_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(), $$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
(int64_t)yylval.intVal, @1); (int64_t)yylval.intVal, @1);
} }
| TOKEN_UINT64DOTDOTDOT_CONSTANT { | TOKEN_UINT64DOTDOTDOT_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(), $$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
(uint64_t)yylval.intVal, @1); (uint64_t)yylval.intVal, @1);
} }
; ;
@@ -1749,7 +1749,7 @@ foreach_dimension_list
foreach_unique_scope foreach_unique_scope
: TOKEN_FOREACH_UNIQUE { m->symbolTable->PushScope(); } : TOKEN_FOREACH_UNIQUE { m->symbolTable->PushScope(); }
; ;
foreach_unique_identifier foreach_unique_identifier
: TOKEN_IDENTIFIER { $$ = yylval.stringVal->c_str(); } : TOKEN_IDENTIFIER { $$ = yylval.stringVal->c_str(); }
; ;
@@ -1764,11 +1764,11 @@ iteration_statement
| TOKEN_CDO statement TOKEN_WHILE '(' expression ')' ';' | TOKEN_CDO statement TOKEN_WHILE '(' expression ')' ';'
{ $$ = new DoStmt($5, $2, true, @1); } { $$ = new DoStmt($5, $2, true, @1); }
| for_scope '(' for_init_statement for_test ')' statement | for_scope '(' for_init_statement for_test ')' statement
{ $$ = new ForStmt($3, $4, NULL, $6, false, @1); { $$ = new ForStmt($3, $4, NULL, $6, false, @1);
m->symbolTable->PopScope(); m->symbolTable->PopScope();
} }
| for_scope '(' for_init_statement for_test expression ')' statement | for_scope '(' for_init_statement for_test expression ')' statement
{ $$ = new ForStmt($3, $4, new ExprStmt($5, @5), $7, false, @1); { $$ = new ForStmt($3, $4, new ExprStmt($5, @5), $7, false, @1);
m->symbolTable->PopScope(); m->symbolTable->PopScope();
} }
| cfor_scope '(' for_init_statement for_test ')' statement | cfor_scope '(' for_init_statement for_test ')' statement
@@ -1847,7 +1847,7 @@ iteration_statement
m->symbolTable->PopScope(); m->symbolTable->PopScope();
} }
| foreach_unique_scope '(' foreach_unique_identifier TOKEN_IN | foreach_unique_scope '(' foreach_unique_identifier TOKEN_IN
expression ')' expression ')'
{ {
Expr *expr = $5; Expr *expr = $5;
const Type *type; const Type *type;
@@ -1905,11 +1905,11 @@ unmasked_statement
print_statement print_statement
: TOKEN_PRINT '(' string_constant ')' ';' : TOKEN_PRINT '(' string_constant ')' ';'
{ {
$$ = new PrintStmt(*$3, NULL, @1); $$ = new PrintStmt(*$3, NULL, @1);
} }
| TOKEN_PRINT '(' string_constant ',' argument_expression_list ')' ';' | TOKEN_PRINT '(' string_constant ',' argument_expression_list ')' ';'
{ {
$$ = new PrintStmt(*$3, $5, @1); $$ = new PrintStmt(*$3, $5, @1);
} }
; ;
@@ -1934,8 +1934,8 @@ external_declaration
if ($3 != NULL) if ($3 != NULL)
m->AddExportedTypes(*$3); m->AddExportedTypes(*$3);
} }
| declaration | declaration
{ {
if ($1 != NULL) if ($1 != NULL)
for (unsigned int i = 0; i < $1->declarators.size(); ++i) for (unsigned int i = 0; i < $1->declarators.size(); ++i)
lAddDeclaration($1->declSpecs, $1->declarators[i]); lAddDeclaration($1->declSpecs, $1->declarators[i]);
@@ -1944,14 +1944,14 @@ external_declaration
; ;
function_definition function_definition
: declaration_specifiers declarator : declaration_specifiers declarator
{ {
lAddDeclaration($1, $2); lAddDeclaration($1, $2);
lAddFunctionParams($2); lAddFunctionParams($2);
lAddMaskToSymbolTable(@2); lAddMaskToSymbolTable(@2);
if ($1->typeQualifiers & TYPEQUAL_TASK) if ($1->typeQualifiers & TYPEQUAL_TASK)
lAddThreadIndexCountToSymbolTable(@2); lAddThreadIndexCountToSymbolTable(@2);
} }
compound_statement compound_statement
{ {
if ($2 != NULL) { if ($2 != NULL) {
@@ -1970,7 +1970,7 @@ function_definition
m->symbolTable->PopScope(); // push in lAddFunctionParams(); m->symbolTable->PopScope(); // push in lAddFunctionParams();
} }
/* function with no declared return type?? /* function with no declared return type??
func(...) func(...)
| declarator { lAddFunctionParams($1); } compound_statement | declarator { lAddFunctionParams($1); } compound_statement
{ {
m->AddFunction(new DeclSpecs(XXX, $1, $3); m->AddFunction(new DeclSpecs(XXX, $1, $3);
@@ -2002,34 +2002,34 @@ lYYTNameErr (char *yyres, const char *yystr)
else else
return yystpcpy(yyres, n.c_str()) - yyres; return yystpcpy(yyres, n.c_str()) - yyres;
} }
if (*yystr == '"') if (*yystr == '"')
{ {
YYSIZE_T yyn = 0; YYSIZE_T yyn = 0;
char const *yyp = yystr; char const *yyp = yystr;
for (;;) for (;;)
switch (*++yyp) switch (*++yyp)
{ {
case '\'': case '\'':
case ',': case ',':
goto do_not_strip_quotes; goto do_not_strip_quotes;
case '\\': case '\\':
if (*++yyp != '\\') if (*++yyp != '\\')
goto do_not_strip_quotes; goto do_not_strip_quotes;
/* Fall through. */ /* Fall through. */
default: default:
if (yyres) if (yyres)
yyres[yyn] = *yyp; yyres[yyn] = *yyp;
yyn++; yyn++;
break; break;
case '"': case '"':
if (yyres) if (yyres)
yyres[yyn] = '\0'; yyres[yyn] = '\0';
return yyn; return yyn;
} }
do_not_strip_quotes: ; do_not_strip_quotes: ;
} }
@@ -2085,7 +2085,7 @@ lAddDeclaration(DeclSpecs *ds, Declarator *decl) {
} }
decl->type = decl->type->ResolveUnboundVariability(Variability::Varying); decl->type = decl->type->ResolveUnboundVariability(Variability::Varying);
const FunctionType *ft = CastType<FunctionType>(decl->type); const FunctionType *ft = CastType<FunctionType>(decl->type);
if (ft != NULL) { if (ft != NULL) {
bool isInline = (ds->typeQualifiers & TYPEQUAL_INLINE); bool isInline = (ds->typeQualifiers & TYPEQUAL_INLINE);
@@ -2113,7 +2113,7 @@ lAddFunctionParams(Declarator *decl) {
return; return;
} }
// walk down to the declarator for the function itself // walk down to the declarator for the function itself
while (decl->kind != DK_FUNCTION && decl->child != NULL) while (decl->kind != DK_FUNCTION && decl->child != NULL)
decl = decl->child; decl = decl->child;
if (decl->kind != DK_FUNCTION) { if (decl->kind != DK_FUNCTION) {
@@ -2265,13 +2265,13 @@ lCreateEnumType(const char *name, std::vector<Symbol *> *enums, SourcePos pos) {
/** Given an array of enumerator symbols, make sure each of them has a /** Given an array of enumerator symbols, make sure each of them has a
ConstExpr * in their Symbol::constValue member that stores their ConstExpr * in their Symbol::constValue member that stores their
unsigned integer value. Symbols that had values explicitly provided unsigned integer value. Symbols that had values explicitly provided
in the source file will already have ConstExpr * set; we just need in the source file will already have ConstExpr * set; we just need
to set the values for the others here. to set the values for the others here.
*/ */
static void static void
lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums, lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
const EnumType *enumType) { const EnumType *enumType) {
enumType = enumType->GetAsConstType(); enumType = enumType->GetAsConstType();
enumType = enumType->GetAsUniformType(); enumType = enumType->GetAsUniformType();
@@ -2304,7 +2304,7 @@ lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
AssertPos(enums[i]->pos, enums[i]->constValue != NULL); AssertPos(enums[i]->pos, enums[i]->constValue != NULL);
} }
else { else {
enums[i]->constValue = new ConstExpr(enumType, nextVal++, enums[i]->constValue = new ConstExpr(enumType, nextVal++,
enums[i]->pos); enums[i]->pos);
} }
} }

294
stmt.cpp
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file stmt.cpp /** @file stmt.cpp
@@ -81,18 +81,18 @@ Stmt::Optimize() {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// ExprStmt // ExprStmt
ExprStmt::ExprStmt(Expr *e, SourcePos p) ExprStmt::ExprStmt(Expr *e, SourcePos p)
: Stmt(p) { : Stmt(p) {
expr = e; expr = e;
} }
void void
ExprStmt::EmitCode(FunctionEmitContext *ctx) const { ExprStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
ctx->SetDebugPos(pos); ctx->SetDebugPos(pos);
if (expr) if (expr)
expr->GetValue(ctx); expr->GetValue(ctx);
} }
@@ -105,7 +105,7 @@ ExprStmt::TypeCheck() {
void void
ExprStmt::Print(int indent) const { ExprStmt::Print(int indent) const {
if (!expr) if (!expr)
return; return;
printf("%*c", indent, ' '); printf("%*c", indent, ' ');
@@ -141,11 +141,11 @@ lHasUnsizedArrays(const Type *type) {
else else
return lHasUnsizedArrays(at->GetElementType()); return lHasUnsizedArrays(at->GetElementType());
} }
void void
DeclStmt::EmitCode(FunctionEmitContext *ctx) const { DeclStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
for (unsigned int i = 0; i < vars.size(); ++i) { for (unsigned int i = 0; i < vars.size(); ++i) {
@@ -236,13 +236,13 @@ DeclStmt::EmitCode(FunctionEmitContext *ctx) const {
// Allocate space for the static variable in global scope, so // Allocate space for the static variable in global scope, so
// that it persists across function calls // that it persists across function calls
sym->storagePtr = sym->storagePtr =
new llvm::GlobalVariable(*m->module, llvmType, new llvm::GlobalVariable(*m->module, llvmType,
sym->type->IsConstType(), sym->type->IsConstType(),
llvm::GlobalValue::InternalLinkage, cinit, llvm::GlobalValue::InternalLinkage, cinit,
llvm::Twine("static.") + llvm::Twine("static.") +
llvm::Twine(sym->pos.first_line) + llvm::Twine(sym->pos.first_line) +
llvm::Twine(".") + sym->name.c_str()); llvm::Twine(".") + sym->name.c_str());
// Tell the FunctionEmitContext about the variable // Tell the FunctionEmitContext about the variable
ctx->EmitVariableDebugInfo(sym); ctx->EmitVariableDebugInfo(sym);
} }
else { else {
@@ -282,7 +282,7 @@ DeclStmt::Optimize() {
// computing array sizes from non-trivial expressions is // computing array sizes from non-trivial expressions is
// consequently limited. // consequently limited.
Symbol *sym = vars[i].sym; Symbol *sym = vars[i].sym;
if (sym->type && sym->type->IsConstType() && if (sym->type && sym->type->IsConstType() &&
Type::Equal(init->GetType(), sym->type)) Type::Equal(init->GetType(), sym->type))
sym->constValue = dynamic_cast<ConstExpr *>(init); sym->constValue = dynamic_cast<ConstExpr *>(init);
} }
@@ -329,7 +329,7 @@ DeclStmt::Print(int indent) const {
printf("%*cDecl Stmt:", indent, ' '); printf("%*cDecl Stmt:", indent, ' ');
pos.Print(); pos.Print();
for (unsigned int i = 0; i < vars.size(); ++i) { for (unsigned int i = 0; i < vars.size(); ++i) {
printf("%*cVariable %s (%s)", indent+4, ' ', printf("%*cVariable %s (%s)", indent+4, ' ',
vars[i].sym->name.c_str(), vars[i].sym->name.c_str(),
vars[i].sym->type->GetString().c_str()); vars[i].sym->type->GetString().c_str());
if (vars[i].init != NULL) { if (vars[i].init != NULL) {
@@ -351,8 +351,8 @@ DeclStmt::EstimateCost() const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// IfStmt // IfStmt
IfStmt::IfStmt(Expr *t, Stmt *ts, Stmt *fs, bool checkCoherence, SourcePos p) IfStmt::IfStmt(Expr *t, Stmt *ts, Stmt *fs, bool checkCoherence, SourcePos p)
: Stmt(p), test(t), trueStmts(ts), falseStmts(fs), : Stmt(p), test(t), trueStmts(ts), falseStmts(fs),
doAllCheck(checkCoherence && doAllCheck(checkCoherence &&
!g->opt.disableCoherentControlFlow) { !g->opt.disableCoherentControlFlow) {
} }
@@ -399,9 +399,9 @@ IfStmt::EmitCode(FunctionEmitContext *ctx) const {
// First check all of the things that might happen due to errors // First check all of the things that might happen due to errors
// earlier in compilation and bail out if needed so that we don't // earlier in compilation and bail out if needed so that we don't
// dereference NULL pointers in the below... // dereference NULL pointers in the below...
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
if (!test) if (!test)
return; return;
const Type *testType = test->GetType(); const Type *testType = test->GetType();
if (!testType) if (!testType)
@@ -433,7 +433,7 @@ IfStmt::EmitCode(FunctionEmitContext *ctx) const {
// Emit code for the 'true' case // Emit code for the 'true' case
ctx->SetCurrentBasicBlock(bthen); ctx->SetCurrentBasicBlock(bthen);
lEmitIfStatements(ctx, trueStmts, "true"); lEmitIfStatements(ctx, trueStmts, "true");
if (ctx->GetCurrentBasicBlock()) if (ctx->GetCurrentBasicBlock())
ctx->BranchInst(bexit); ctx->BranchInst(bexit);
// Emit code for the 'false' case // Emit code for the 'false' case
@@ -466,10 +466,10 @@ IfStmt::TypeCheck() {
if (test != NULL) { if (test != NULL) {
const Type *testType = test->GetType(); const Type *testType = test->GetType();
if (testType != NULL) { if (testType != NULL) {
bool isUniform = (testType->IsUniformType() && bool isUniform = (testType->IsUniformType() &&
!g->opt.disableUniformControlFlow); !g->opt.disableUniformControlFlow);
test = TypeConvertExpr(test, isUniform ? AtomicType::UniformBool : test = TypeConvertExpr(test, isUniform ? AtomicType::UniformBool :
AtomicType::VaryingBool, AtomicType::VaryingBool,
"\"if\" statement test"); "\"if\" statement test");
if (test == NULL) if (test == NULL)
return NULL; return NULL;
@@ -509,17 +509,17 @@ IfStmt::Print(int indent) const {
/** Emit code to run both the true and false statements for the if test, /** Emit code to run both the true and false statements for the if test,
with the mask set appropriately before running each one. with the mask set appropriately before running each one.
*/ */
void void
IfStmt::emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask, IfStmt::emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
llvm::Value *test) const { llvm::Value *test) const {
if (trueStmts) { if (trueStmts) {
ctx->SetInternalMaskAnd(oldMask, test); ctx->SetInternalMaskAnd(oldMask, test);
lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements"); lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements");
// under varying control flow,, returns can't stop instruction // under varying control flow,, returns can't stop instruction
// emission, so this better be non-NULL... // emission, so this better be non-NULL...
AssertPos(ctx->GetDebugPos(), ctx->GetCurrentBasicBlock()); AssertPos(ctx->GetDebugPos(), ctx->GetCurrentBasicBlock());
} }
if (falseStmts) { if (falseStmts) {
ctx->SetInternalMaskAndNot(oldMask, test); ctx->SetInternalMaskAndNot(oldMask, test);
@@ -544,14 +544,14 @@ IfStmt::emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *ltest) const {
llvm::BasicBlock *bMixedOn = ctx->CreateBasicBlock("cif_mask_mixed"); llvm::BasicBlock *bMixedOn = ctx->CreateBasicBlock("cif_mask_mixed");
llvm::BasicBlock *bDone = ctx->CreateBasicBlock("cif_done"); llvm::BasicBlock *bDone = ctx->CreateBasicBlock("cif_done");
// Jump to either bAllOn or bMixedOn, depending on the mask's value // Jump to either bAllOn or bMixedOn, depending on the mask's value
llvm::Value *maskAllQ = ctx->All(ctx->GetFullMask()); llvm::Value *maskAllQ = ctx->All(ctx->GetFullMask());
ctx->BranchInst(bAllOn, bMixedOn, maskAllQ); ctx->BranchInst(bAllOn, bMixedOn, maskAllQ);
// Emit code for the 'mask all on' case // Emit code for the 'mask all on' case
ctx->SetCurrentBasicBlock(bAllOn); ctx->SetCurrentBasicBlock(bAllOn);
emitMaskAllOn(ctx, ltest, bDone); emitMaskAllOn(ctx, ltest, bDone);
// And emit code for the mixed mask case // And emit code for the mixed mask case
ctx->SetCurrentBasicBlock(bMixedOn); ctx->SetCurrentBasicBlock(bMixedOn);
emitMaskMixed(ctx, oldMask, ltest, bDone); emitMaskMixed(ctx, oldMask, ltest, bDone);
@@ -580,7 +580,7 @@ IfStmt::emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *ltest) const {
// //
// where our use of blend for conditional assignments doesn't check // where our use of blend for conditional assignments doesn't check
// for the 'all lanes' off case. // for the 'all lanes' off case.
int trueFalseCost = (::EstimateCost(trueStmts) + int trueFalseCost = (::EstimateCost(trueStmts) +
::EstimateCost(falseStmts)); ::EstimateCost(falseStmts));
bool costIsAcceptable = (trueFalseCost < bool costIsAcceptable = (trueFalseCost <
PREDICATE_SAFE_IF_STATEMENT_COST); PREDICATE_SAFE_IF_STATEMENT_COST);
@@ -591,7 +591,7 @@ IfStmt::emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *ltest) const {
Debug(pos, "If statement: true cost %d (safe %d), false cost %d (safe %d).", Debug(pos, "If statement: true cost %d (safe %d), false cost %d (safe %d).",
::EstimateCost(trueStmts), (int)SafeToRunWithMaskAllOff(trueStmts), ::EstimateCost(trueStmts), (int)SafeToRunWithMaskAllOff(trueStmts),
::EstimateCost(falseStmts), (int)SafeToRunWithMaskAllOff(falseStmts)); ::EstimateCost(falseStmts), (int)SafeToRunWithMaskAllOff(falseStmts));
if (safeToRunWithAllLanesOff && if (safeToRunWithAllLanesOff &&
(costIsAcceptable || g->opt.disableCoherentControlFlow)) { (costIsAcceptable || g->opt.disableCoherentControlFlow)) {
ctx->StartVaryingIf(oldMask); ctx->StartVaryingIf(oldMask);
@@ -612,7 +612,7 @@ IfStmt::emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *ltest) const {
mask is all on going into the 'if'. mask is all on going into the 'if'.
*/ */
void void
IfStmt::emitMaskAllOn(FunctionEmitContext *ctx, llvm::Value *ltest, IfStmt::emitMaskAllOn(FunctionEmitContext *ctx, llvm::Value *ltest,
llvm::BasicBlock *bDone) const { llvm::BasicBlock *bDone) const {
// We start by explicitly storing "all on" into the mask mask. Note // We start by explicitly storing "all on" into the mask mask. Note
// that this doesn't change its actual value, but doing so lets the // that this doesn't change its actual value, but doing so lets the
@@ -682,7 +682,7 @@ IfStmt::emitMaskAllOn(FunctionEmitContext *ctx, llvm::Value *ltest,
on/off going into it. on/off going into it.
*/ */
void void
IfStmt::emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask, IfStmt::emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
llvm::Value *ltest, llvm::BasicBlock *bDone) const { llvm::Value *ltest, llvm::BasicBlock *bDone) const {
ctx->StartVaryingIf(oldMask); ctx->StartVaryingIf(oldMask);
llvm::BasicBlock *bNext = ctx->CreateBasicBlock("safe_if_after_true"); llvm::BasicBlock *bNext = ctx->CreateBasicBlock("safe_if_after_true");
@@ -699,7 +699,7 @@ IfStmt::emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
ctx->SetCurrentBasicBlock(bRunTrue); ctx->SetCurrentBasicBlock(bRunTrue);
if (trueStmts != NULL) if (trueStmts != NULL)
lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements"); lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements");
AssertPos(pos, ctx->GetCurrentBasicBlock()); AssertPos(pos, ctx->GetCurrentBasicBlock());
ctx->BranchInst(bNext); ctx->BranchInst(bNext);
ctx->SetCurrentBasicBlock(bNext); ctx->SetCurrentBasicBlock(bNext);
@@ -801,7 +801,7 @@ lVaryingBCPostFunc(ASTNode *node, void *d) {
flow. We need to detect this case for loops since what might otherwise flow. We need to detect this case for loops since what might otherwise
look like a 'uniform' loop needs to have code emitted to do all of the look like a 'uniform' loop needs to have code emitted to do all of the
lane management stuff if this is the case. lane management stuff if this is the case.
*/ */
static bool static bool
lHasVaryingBreakOrContinue(Stmt *stmt) { lHasVaryingBreakOrContinue(Stmt *stmt) {
VaryingBCCheckInfo info; VaryingBCCheckInfo info;
@@ -810,8 +810,8 @@ lHasVaryingBreakOrContinue(Stmt *stmt) {
} }
DoStmt::DoStmt(Expr *t, Stmt *s, bool cc, SourcePos p) DoStmt::DoStmt(Expr *t, Stmt *s, bool cc, SourcePos p)
: Stmt(p), testExpr(t), bodyStmts(s), : Stmt(p), testExpr(t), bodyStmts(s),
doCoherentCheck(cc && !g->opt.disableCoherentControlFlow) { doCoherentCheck(cc && !g->opt.disableCoherentControlFlow) {
} }
@@ -819,9 +819,9 @@ DoStmt::DoStmt(Expr *t, Stmt *s, bool cc, SourcePos p)
void DoStmt::EmitCode(FunctionEmitContext *ctx) const { void DoStmt::EmitCode(FunctionEmitContext *ctx) const {
// Check for things that could be NULL due to earlier errors during // Check for things that could be NULL due to earlier errors during
// compilation. // compilation.
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
if (!testExpr || !testExpr->GetType()) if (!testExpr || !testExpr->GetType())
return; return;
bool uniformTest = testExpr->GetType()->IsUniformType(); bool uniformTest = testExpr->GetType()->IsUniformType();
@@ -984,15 +984,15 @@ DoStmt::Print(int indent) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// ForStmt // ForStmt
ForStmt::ForStmt(Stmt *i, Expr *t, Stmt *s, Stmt *st, bool cc, SourcePos p) ForStmt::ForStmt(Stmt *i, Expr *t, Stmt *s, Stmt *st, bool cc, SourcePos p)
: Stmt(p), init(i), test(t), step(s), stmts(st), : Stmt(p), init(i), test(t), step(s), stmts(st),
doCoherentCheck(cc && !g->opt.disableCoherentControlFlow) { doCoherentCheck(cc && !g->opt.disableCoherentControlFlow) {
} }
void void
ForStmt::EmitCode(FunctionEmitContext *ctx) const { ForStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
llvm::BasicBlock *btest = ctx->CreateBasicBlock("for_test"); llvm::BasicBlock *btest = ctx->CreateBasicBlock("for_test");
@@ -1176,14 +1176,14 @@ ForStmt::Print(int indent) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// BreakStmt // BreakStmt
BreakStmt::BreakStmt(SourcePos p) BreakStmt::BreakStmt(SourcePos p)
: Stmt(p) { : Stmt(p) {
} }
void void
BreakStmt::EmitCode(FunctionEmitContext *ctx) const { BreakStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
ctx->SetDebugPos(pos); ctx->SetDebugPos(pos);
@@ -1214,14 +1214,14 @@ BreakStmt::Print(int indent) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// ContinueStmt // ContinueStmt
ContinueStmt::ContinueStmt(SourcePos p) ContinueStmt::ContinueStmt(SourcePos p)
: Stmt(p) { : Stmt(p) {
} }
void void
ContinueStmt::EmitCode(FunctionEmitContext *ctx) const { ContinueStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
ctx->SetDebugPos(pos); ctx->SetDebugPos(pos);
@@ -1252,9 +1252,9 @@ ContinueStmt::Print(int indent) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// ForeachStmt // ForeachStmt
ForeachStmt::ForeachStmt(const std::vector<Symbol *> &lvs, ForeachStmt::ForeachStmt(const std::vector<Symbol *> &lvs,
const std::vector<Expr *> &se, const std::vector<Expr *> &se,
const std::vector<Expr *> &ee, const std::vector<Expr *> &ee,
Stmt *s, bool t, SourcePos pos) Stmt *s, bool t, SourcePos pos)
: Stmt(pos), dimVariables(lvs), startExprs(se), endExprs(ee), isTiled(t), : Stmt(pos), dimVariables(lvs), startExprs(se), endExprs(ee), isTiled(t),
stmts(s) { stmts(s) {
@@ -1266,16 +1266,16 @@ ForeachStmt::ForeachStmt(const std::vector<Symbol *> &lvs,
values for use within the loop body. values for use within the loop body.
*/ */
static llvm::Value * static llvm::Value *
lUpdateVaryingCounter(int dim, int nDims, FunctionEmitContext *ctx, lUpdateVaryingCounter(int dim, int nDims, FunctionEmitContext *ctx,
llvm::Value *uniformCounterPtr, llvm::Value *uniformCounterPtr,
llvm::Value *varyingCounterPtr, llvm::Value *varyingCounterPtr,
const std::vector<int> &spans) { const std::vector<int> &spans) {
// Smear the uniform counter value out to be varying // Smear the uniform counter value out to be varying
llvm::Value *counter = ctx->LoadInst(uniformCounterPtr); llvm::Value *counter = ctx->LoadInst(uniformCounterPtr);
llvm::Value *smearCounter = llvm::Value *smearCounter =
llvm::UndefValue::get(LLVMTypes::Int32VectorType); llvm::UndefValue::get(LLVMTypes::Int32VectorType);
for (int i = 0; i < g->target.vectorWidth; ++i) for (int i = 0; i < g->target.vectorWidth; ++i)
smearCounter = smearCounter =
ctx->InsertInst(smearCounter, counter, i, "smear_counter"); ctx->InsertInst(smearCounter, counter, i, "smear_counter");
// Figure out the offsets; this is a little bit tricky. As an example, // Figure out the offsets; this is a little bit tricky. As an example,
@@ -1300,7 +1300,7 @@ lUpdateVaryingCounter(int dim, int nDims, FunctionEmitContext *ctx,
// Add the deltas to compute the varying counter values; store the // Add the deltas to compute the varying counter values; store the
// result to memory and then return it directly as well. // result to memory and then return it directly as well.
llvm::Value *varyingCounter = llvm::Value *varyingCounter =
ctx->BinaryOperator(llvm::Instruction::Add, smearCounter, ctx->BinaryOperator(llvm::Instruction::Add, smearCounter,
LLVMInt32Vector(delta), "iter_val"); LLVMInt32Vector(delta), "iter_val");
ctx->StoreInst(varyingCounter, varyingCounterPtr); ctx->StoreInst(varyingCounter, varyingCounterPtr);
@@ -1349,7 +1349,7 @@ lGetSpans(int dimsLeft, int nDims, int itemsLeft, bool isTiled, int *a) {
// 16-wide. // 16-wide.
*a = 4; *a = 4;
else else
// Otherwise give this dimension a span of two. // Otherwise give this dimension a span of two.
*a = 2; *a = 2;
lGetSpans(dimsLeft-1, nDims, itemsLeft / *a, isTiled, a+1); lGetSpans(dimsLeft-1, nDims, itemsLeft / *a, isTiled, a+1);
@@ -1364,7 +1364,7 @@ lGetSpans(int dimsLeft, int nDims, int itemsLeft, bool isTiled, int *a) {
*/ */
void void
ForeachStmt::EmitCode(FunctionEmitContext *ctx) const { ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
if (ctx->GetCurrentBasicBlock() == NULL || stmts == NULL) if (ctx->GetCurrentBasicBlock() == NULL || stmts == NULL)
return; return;
llvm::BasicBlock *bbFullBody = ctx->CreateBasicBlock("foreach_full_body"); llvm::BasicBlock *bbFullBody = ctx->CreateBasicBlock("foreach_full_body");
@@ -1381,7 +1381,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
ctx->SetFunctionMask(LLVMMaskAllOn); ctx->SetFunctionMask(LLVMMaskAllOn);
// This should be caught during typechecking // This should be caught during typechecking
AssertPos(pos, startExprs.size() == dimVariables.size() && AssertPos(pos, startExprs.size() == dimVariables.size() &&
endExprs.size() == dimVariables.size()); endExprs.size() == dimVariables.size());
int nDims = (int)dimVariables.size(); int nDims = (int)dimVariables.size();
@@ -1413,7 +1413,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
endVals.push_back(ev); endVals.push_back(ev);
// nItems = endVal - startVal // nItems = endVal - startVal
llvm::Value *nItems = llvm::Value *nItems =
ctx->BinaryOperator(llvm::Instruction::Sub, ev, sv, "nitems"); ctx->BinaryOperator(llvm::Instruction::Sub, ev, sv, "nitems");
// nExtras = nItems % (span for this dimension) // nExtras = nItems % (span for this dimension)
@@ -1432,15 +1432,15 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
// goes from startVal to endVal, in steps of the span for this // goes from startVal to endVal, in steps of the span for this
// dimension. Its value is only used internally here for looping // dimension. Its value is only used internally here for looping
// logic and isn't directly available in the user's program code. // logic and isn't directly available in the user's program code.
uniformCounterPtrs.push_back(ctx->AllocaInst(LLVMTypes::Int32Type, uniformCounterPtrs.push_back(ctx->AllocaInst(LLVMTypes::Int32Type,
"counter")); "counter"));
ctx->StoreInst(startVals[i], uniformCounterPtrs[i]); ctx->StoreInst(startVals[i], uniformCounterPtrs[i]);
// There is also a varying variable that holds the set of index // There is also a varying variable that holds the set of index
// values for each dimension in the current loop iteration; this is // values for each dimension in the current loop iteration; this is
// the value that is program-visible. // the value that is program-visible.
dimVariables[i]->storagePtr = dimVariables[i]->storagePtr =
ctx->AllocaInst(LLVMTypes::Int32VectorType, ctx->AllocaInst(LLVMTypes::Int32VectorType,
dimVariables[i]->name.c_str()); dimVariables[i]->name.c_str());
dimVariables[i]->parentFunction = ctx->GetFunction(); dimVariables[i]->parentFunction = ctx->GetFunction();
ctx->EmitVariableDebugInfo(dimVariables[i]); ctx->EmitVariableDebugInfo(dimVariables[i]);
@@ -1482,7 +1482,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
for (int i = 0; i < nDims-1; ++i) { for (int i = 0; i < nDims-1; ++i) {
ctx->SetCurrentBasicBlock(bbStep[i]); ctx->SetCurrentBasicBlock(bbStep[i]);
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[i]); llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[i]);
llvm::Value *newCounter = llvm::Value *newCounter =
ctx->BinaryOperator(llvm::Instruction::Add, counter, ctx->BinaryOperator(llvm::Instruction::Add, counter,
LLVMInt32(span[i]), "new_counter"); LLVMInt32(span[i]), "new_counter");
ctx->StoreInst(newCounter, uniformCounterPtrs[i]); ctx->StoreInst(newCounter, uniformCounterPtrs[i]);
@@ -1495,15 +1495,15 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
for (int i = 0; i < nDims-1; ++i) { for (int i = 0; i < nDims-1; ++i) {
ctx->SetCurrentBasicBlock(bbTest[i]); ctx->SetCurrentBasicBlock(bbTest[i]);
llvm::Value *haveExtras = llvm::Value *haveExtras =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGT, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGT,
endVals[i], alignedEnd[i], "have_extras"); endVals[i], alignedEnd[i], "have_extras");
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[i], "counter"); llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[i], "counter");
llvm::Value *atAlignedEnd = llvm::Value *atAlignedEnd =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
counter, alignedEnd[i], "at_aligned_end"); counter, alignedEnd[i], "at_aligned_end");
llvm::Value *inEx = llvm::Value *inEx =
ctx->BinaryOperator(llvm::Instruction::And, haveExtras, ctx->BinaryOperator(llvm::Instruction::And, haveExtras,
atAlignedEnd, "in_extras"); atAlignedEnd, "in_extras");
@@ -1513,8 +1513,8 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
inExtras.push_back(ctx->BinaryOperator(llvm::Instruction::Or, inEx, inExtras.push_back(ctx->BinaryOperator(llvm::Instruction::Or, inEx,
inExtras[i-1], "in_extras_all")); inExtras[i-1], "in_extras_all"));
llvm::Value *varyingCounter = llvm::Value *varyingCounter =
lUpdateVaryingCounter(i, nDims, ctx, uniformCounterPtrs[i], lUpdateVaryingCounter(i, nDims, ctx, uniformCounterPtrs[i],
dimVariables[i]->storagePtr, span); dimVariables[i]->storagePtr, span);
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType); llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
@@ -1522,7 +1522,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
smearEnd = ctx->InsertInst(smearEnd, endVals[i], j, "smear_end"); smearEnd = ctx->InsertInst(smearEnd, endVals[i], j, "smear_end");
// Do a vector compare of its value to the end value to generate a // Do a vector compare of its value to the end value to generate a
// mask for this last bit of work. // mask for this last bit of work.
llvm::Value *emask = llvm::Value *emask =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
varyingCounter, smearEnd); varyingCounter, smearEnd);
emask = ctx->I1VecToBoolVec(emask); emask = ctx->I1VecToBoolVec(emask);
@@ -1537,7 +1537,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
ctx->StoreInst(newMask, extrasMaskPtrs[i]); ctx->StoreInst(newMask, extrasMaskPtrs[i]);
} }
llvm::Value *notAtEnd = llvm::Value *notAtEnd =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
counter, endVals[i]); counter, endVals[i]);
ctx->BranchInst(bbTest[i+1], bbReset[i], notAtEnd); ctx->BranchInst(bbTest[i+1], bbReset[i], notAtEnd);
@@ -1576,9 +1576,9 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
// whether any of the enclosing dimensions is partially active // whether any of the enclosing dimensions is partially active
// (i.e. processing extra elements that don't exactly fit into a // (i.e. processing extra elements that don't exactly fit into a
// vector). // vector).
llvm::BasicBlock *bbOuterInExtras = llvm::BasicBlock *bbOuterInExtras =
ctx->CreateBasicBlock("outer_in_extras"); ctx->CreateBasicBlock("outer_in_extras");
llvm::BasicBlock *bbOuterNotInExtras = llvm::BasicBlock *bbOuterNotInExtras =
ctx->CreateBasicBlock("outer_not_in_extras"); ctx->CreateBasicBlock("outer_not_in_extras");
ctx->SetCurrentBasicBlock(bbTest[nDims-1]); ctx->SetCurrentBasicBlock(bbTest[nDims-1]);
@@ -1609,12 +1609,12 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
ctx->SetCurrentBasicBlock(bbOuterInExtras); { ctx->SetCurrentBasicBlock(bbOuterInExtras); {
// Update the varying counter value here, since all subsequent // Update the varying counter value here, since all subsequent
// blocks along this path need it. // blocks along this path need it.
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1], lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
dimVariables[nDims-1]->storagePtr, span); dimVariables[nDims-1]->storagePtr, span);
// here we just check to see if counter < alignedEnd // here we just check to see if counter < alignedEnd
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter"); llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
llvm::Value *beforeAlignedEnd = llvm::Value *beforeAlignedEnd =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
counter, alignedEnd[nDims-1], "before_aligned_end"); counter, alignedEnd[nDims-1], "before_aligned_end");
ctx->BranchInst(bbAllInnerPartialOuter, bbPartial, beforeAlignedEnd); ctx->BranchInst(bbAllInnerPartialOuter, bbPartial, beforeAlignedEnd);
@@ -1624,7 +1624,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
// case where the mask is partially but not fully on. This same block // case where the mask is partially but not fully on. This same block
// runs in multiple cases: both for handling any ragged extra data for // runs in multiple cases: both for handling any ragged extra data for
// the innermost dimension but also when outer dimensions have set the // the innermost dimension but also when outer dimensions have set the
// mask to be partially on. // mask to be partially on.
// //
// The value stored in stepIndexAfterMaskedBodyPtr is used after each // The value stored in stepIndexAfterMaskedBodyPtr is used after each
// execution of the body code to determine whether the innermost index // execution of the body code to determine whether the innermost index
@@ -1660,12 +1660,12 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
// We need to include the effect of the innermost dimension in the mask // We need to include the effect of the innermost dimension in the mask
// for the final bits here // for the final bits here
ctx->SetCurrentBasicBlock(bbPartial); { ctx->SetCurrentBasicBlock(bbPartial); {
llvm::Value *varyingCounter = llvm::Value *varyingCounter =
ctx->LoadInst(dimVariables[nDims-1]->storagePtr); ctx->LoadInst(dimVariables[nDims-1]->storagePtr);
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType); llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
for (int j = 0; j < g->target.vectorWidth; ++j) for (int j = 0; j < g->target.vectorWidth; ++j)
smearEnd = ctx->InsertInst(smearEnd, endVals[nDims-1], j, "smear_end"); smearEnd = ctx->InsertInst(smearEnd, endVals[nDims-1], j, "smear_end");
llvm::Value *emask = llvm::Value *emask =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
varyingCounter, smearEnd); varyingCounter, smearEnd);
emask = ctx->I1VecToBoolVec(emask); emask = ctx->I1VecToBoolVec(emask);
@@ -1701,7 +1701,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
ctx->CreateBasicBlock("partial_inner_all_outer"); ctx->CreateBasicBlock("partial_inner_all_outer");
ctx->SetCurrentBasicBlock(bbOuterNotInExtras); { ctx->SetCurrentBasicBlock(bbOuterNotInExtras); {
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter"); llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
llvm::Value *beforeAlignedEnd = llvm::Value *beforeAlignedEnd =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
counter, alignedEnd[nDims-1], "before_aligned_end"); counter, alignedEnd[nDims-1], "before_aligned_end");
ctx->BranchInst(bbFullBody, bbPartialInnerAllOuter, ctx->BranchInst(bbFullBody, bbPartialInnerAllOuter,
@@ -1714,12 +1714,12 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
// on'. This ends up being relatively straightforward: just update the // on'. This ends up being relatively straightforward: just update the
// value of the varying loop counter and have the statements in the // value of the varying loop counter and have the statements in the
// loop body emit their code. // loop body emit their code.
llvm::BasicBlock *bbFullBodyContinue = llvm::BasicBlock *bbFullBodyContinue =
ctx->CreateBasicBlock("foreach_full_continue"); ctx->CreateBasicBlock("foreach_full_continue");
ctx->SetCurrentBasicBlock(bbFullBody); { ctx->SetCurrentBasicBlock(bbFullBody); {
ctx->SetInternalMask(LLVMMaskAllOn); ctx->SetInternalMask(LLVMMaskAllOn);
ctx->SetBlockEntryMask(LLVMMaskAllOn); ctx->SetBlockEntryMask(LLVMMaskAllOn);
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1], lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
dimVariables[nDims-1]->storagePtr, span); dimVariables[nDims-1]->storagePtr, span);
ctx->SetContinueTarget(bbFullBodyContinue); ctx->SetContinueTarget(bbFullBodyContinue);
ctx->AddInstrumentationPoint("foreach loop body (all on)"); ctx->AddInstrumentationPoint("foreach loop body (all on)");
@@ -1730,7 +1730,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
ctx->SetCurrentBasicBlock(bbFullBodyContinue); { ctx->SetCurrentBasicBlock(bbFullBodyContinue); {
ctx->RestoreContinuedLanes(); ctx->RestoreContinuedLanes();
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1]); llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1]);
llvm::Value *newCounter = llvm::Value *newCounter =
ctx->BinaryOperator(llvm::Instruction::Add, counter, ctx->BinaryOperator(llvm::Instruction::Add, counter,
LLVMInt32(span[nDims-1]), "new_counter"); LLVMInt32(span[nDims-1]), "new_counter");
ctx->StoreInst(newCounter, uniformCounterPtrs[nDims-1]); ctx->StoreInst(newCounter, uniformCounterPtrs[nDims-1]);
@@ -1741,11 +1741,11 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
// We're done running blocks with the mask all on; see if the counter is // We're done running blocks with the mask all on; see if the counter is
// less than the end value, in which case we need to run the body one // less than the end value, in which case we need to run the body one
// more time to get the extra bits. // more time to get the extra bits.
llvm::BasicBlock *bbSetInnerMask = llvm::BasicBlock *bbSetInnerMask =
ctx->CreateBasicBlock("partial_inner_only"); ctx->CreateBasicBlock("partial_inner_only");
ctx->SetCurrentBasicBlock(bbPartialInnerAllOuter); { ctx->SetCurrentBasicBlock(bbPartialInnerAllOuter); {
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter"); llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
llvm::Value *beforeFullEnd = llvm::Value *beforeFullEnd =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
counter, endVals[nDims-1], "before_full_end"); counter, endVals[nDims-1], "before_full_end");
ctx->BranchInst(bbSetInnerMask, bbReset[nDims-1], beforeFullEnd); ctx->BranchInst(bbSetInnerMask, bbReset[nDims-1], beforeFullEnd);
@@ -1755,13 +1755,13 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
// The outer dimensions are all on, so the mask is just given by the // The outer dimensions are all on, so the mask is just given by the
// mask for the innermost dimension // mask for the innermost dimension
ctx->SetCurrentBasicBlock(bbSetInnerMask); { ctx->SetCurrentBasicBlock(bbSetInnerMask); {
llvm::Value *varyingCounter = llvm::Value *varyingCounter =
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1], lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
dimVariables[nDims-1]->storagePtr, span); dimVariables[nDims-1]->storagePtr, span);
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType); llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
for (int j = 0; j < g->target.vectorWidth; ++j) for (int j = 0; j < g->target.vectorWidth; ++j)
smearEnd = ctx->InsertInst(smearEnd, endVals[nDims-1], j, "smear_end"); smearEnd = ctx->InsertInst(smearEnd, endVals[nDims-1], j, "smear_end");
llvm::Value *emask = llvm::Value *emask =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
varyingCounter, smearEnd); varyingCounter, smearEnd);
emask = ctx->I1VecToBoolVec(emask); emask = ctx->I1VecToBoolVec(emask);
@@ -1778,9 +1778,9 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
// of the statements' code, since the code above is emitted with the // of the statements' code, since the code above is emitted with the
// mask known to be all-on, which in turn leads to more efficient code // mask known to be all-on, which in turn leads to more efficient code
// for that case. // for that case.
llvm::BasicBlock *bbStepInnerIndex = llvm::BasicBlock *bbStepInnerIndex =
ctx->CreateBasicBlock("step_inner_index"); ctx->CreateBasicBlock("step_inner_index");
llvm::BasicBlock *bbMaskedBodyContinue = llvm::BasicBlock *bbMaskedBodyContinue =
ctx->CreateBasicBlock("foreach_masked_continue"); ctx->CreateBasicBlock("foreach_masked_continue");
ctx->SetCurrentBasicBlock(bbMaskedBody); { ctx->SetCurrentBasicBlock(bbMaskedBody); {
ctx->AddInstrumentationPoint("foreach loop body (masked)"); ctx->AddInstrumentationPoint("foreach loop body (masked)");
@@ -1802,7 +1802,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
// innermost for loop over full vectors. // innermost for loop over full vectors.
ctx->SetCurrentBasicBlock(bbStepInnerIndex); { ctx->SetCurrentBasicBlock(bbStepInnerIndex); {
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1]); llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1]);
llvm::Value *newCounter = llvm::Value *newCounter =
ctx->BinaryOperator(llvm::Instruction::Add, counter, ctx->BinaryOperator(llvm::Instruction::Add, counter,
LLVMInt32(span[nDims-1]), "new_counter"); LLVMInt32(span[nDims-1]), "new_counter");
ctx->StoreInst(newCounter, uniformCounterPtrs[nDims-1]); ctx->StoreInst(newCounter, uniformCounterPtrs[nDims-1]);
@@ -1826,8 +1826,8 @@ ForeachStmt::TypeCheck() {
bool anyErrors = false; bool anyErrors = false;
for (unsigned int i = 0; i < startExprs.size(); ++i) { for (unsigned int i = 0; i < startExprs.size(); ++i) {
if (startExprs[i] != NULL) if (startExprs[i] != NULL)
startExprs[i] = TypeConvertExpr(startExprs[i], startExprs[i] = TypeConvertExpr(startExprs[i],
AtomicType::UniformInt32, AtomicType::UniformInt32,
"foreach starting value"); "foreach starting value");
anyErrors |= (startExprs[i] == NULL); anyErrors |= (startExprs[i] == NULL);
} }
@@ -1875,12 +1875,12 @@ ForeachStmt::Print(int indent) const {
printf("%*cForeach Stmt", indent, ' '); printf("%*cForeach Stmt", indent, ' ');
pos.Print(); pos.Print();
printf("\n"); printf("\n");
for (unsigned int i = 0; i < dimVariables.size(); ++i) for (unsigned int i = 0; i < dimVariables.size(); ++i)
if (dimVariables[i] != NULL) if (dimVariables[i] != NULL)
printf("%*cVar %d: %s\n", indent+4, ' ', i, printf("%*cVar %d: %s\n", indent+4, ' ', i,
dimVariables[i]->name.c_str()); dimVariables[i]->name.c_str());
else else
printf("%*cVar %d: NULL\n", indent+4, ' ', i); printf("%*cVar %d: NULL\n", indent+4, ' ', i);
printf("Start values:\n"); printf("Start values:\n");
@@ -1917,7 +1917,7 @@ ForeachStmt::Print(int indent) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// ForeachActiveStmt // ForeachActiveStmt
ForeachActiveStmt::ForeachActiveStmt(Symbol *s, Stmt *st, SourcePos pos) ForeachActiveStmt::ForeachActiveStmt(Symbol *s, Stmt *st, SourcePos pos)
: Stmt(pos) { : Stmt(pos) {
sym = s; sym = s;
stmts = st; stmts = st;
@@ -1926,7 +1926,7 @@ ForeachActiveStmt::ForeachActiveStmt(Symbol *s, Stmt *st, SourcePos pos)
void void
ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const { ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
// Allocate storage for the symbol that we'll use for the uniform // Allocate storage for the symbol that we'll use for the uniform
@@ -1936,7 +1936,7 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return; return;
} }
Assert(Type::Equal(sym->type, Assert(Type::Equal(sym->type,
AtomicType::UniformInt64->GetAsConstType())); AtomicType::UniformInt64->GetAsConstType()));
sym->storagePtr = ctx->AllocaInst(LLVMTypes::Int64Type, sym->name.c_str()); sym->storagePtr = ctx->AllocaInst(LLVMTypes::Int64Type, sym->name.c_str());
@@ -1944,22 +1944,22 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
ctx->EmitVariableDebugInfo(sym); ctx->EmitVariableDebugInfo(sym);
// The various basic blocks that we'll need in the below // The various basic blocks that we'll need in the below
llvm::BasicBlock *bbFindNext = llvm::BasicBlock *bbFindNext =
ctx->CreateBasicBlock("foreach_active_find_next"); ctx->CreateBasicBlock("foreach_active_find_next");
llvm::BasicBlock *bbBody = ctx->CreateBasicBlock("foreach_active_body"); llvm::BasicBlock *bbBody = ctx->CreateBasicBlock("foreach_active_body");
llvm::BasicBlock *bbCheckForMore = llvm::BasicBlock *bbCheckForMore =
ctx->CreateBasicBlock("foreach_active_check_for_more"); ctx->CreateBasicBlock("foreach_active_check_for_more");
llvm::BasicBlock *bbDone = ctx->CreateBasicBlock("foreach_active_done"); llvm::BasicBlock *bbDone = ctx->CreateBasicBlock("foreach_active_done");
// Save the old mask so that we can restore it at the end // Save the old mask so that we can restore it at the end
llvm::Value *oldInternalMask = ctx->GetInternalMask(); llvm::Value *oldInternalMask = ctx->GetInternalMask();
// Now, *maskBitsPtr will maintain a bitmask for the lanes that remain // Now, *maskBitsPtr will maintain a bitmask for the lanes that remain
// to be processed by a pass through the loop body. It starts out with // to be processed by a pass through the loop body. It starts out with
// the current execution mask (which should never be all off going in // the current execution mask (which should never be all off going in
// to this)... // to this)...
llvm::Value *oldFullMask = ctx->GetFullMask(); llvm::Value *oldFullMask = ctx->GetFullMask();
llvm::Value *maskBitsPtr = llvm::Value *maskBitsPtr =
ctx->AllocaInst(LLVMTypes::Int64Type, "mask_bits"); ctx->AllocaInst(LLVMTypes::Int64Type, "mask_bits");
llvm::Value *movmsk = ctx->LaneMask(oldFullMask); llvm::Value *movmsk = ctx->LaneMask(oldFullMask);
ctx->StoreInst(movmsk, maskBitsPtr); ctx->StoreInst(movmsk, maskBitsPtr);
@@ -1971,13 +1971,13 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
// Onward to find the first set of program instance to run the loop for // Onward to find the first set of program instance to run the loop for
ctx->BranchInst(bbFindNext); ctx->BranchInst(bbFindNext);
ctx->SetCurrentBasicBlock(bbFindNext); { ctx->SetCurrentBasicBlock(bbFindNext); {
// Load the bitmask of the lanes left to be processed // Load the bitmask of the lanes left to be processed
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits"); llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
// Find the index of the first set bit in the mask // Find the index of the first set bit in the mask
llvm::Function *ctlzFunc = llvm::Function *ctlzFunc =
m->module->getFunction("__count_trailing_zeros_i64"); m->module->getFunction("__count_trailing_zeros_i64");
Assert(ctlzFunc != NULL); Assert(ctlzFunc != NULL);
llvm::Value *firstSet = ctx->CallInst(ctlzFunc, NULL, remainingBits, llvm::Value *firstSet = ctx->CallInst(ctlzFunc, NULL, remainingBits,
@@ -1993,20 +1993,20 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
// math...) // math...)
// Get the "program index" vector value // Get the "program index" vector value
llvm::Value *programIndex = llvm::Value *programIndex =
llvm::UndefValue::get(LLVMTypes::Int32VectorType); llvm::UndefValue::get(LLVMTypes::Int32VectorType);
for (int i = 0; i < g->target.vectorWidth; ++i) for (int i = 0; i < g->target.vectorWidth; ++i)
programIndex = ctx->InsertInst(programIndex, LLVMInt32(i), i, programIndex = ctx->InsertInst(programIndex, LLVMInt32(i), i,
"prog_index"); "prog_index");
// And smear the current lane out to a vector // And smear the current lane out to a vector
llvm::Value *firstSet32 = llvm::Value *firstSet32 =
ctx->TruncInst(firstSet, LLVMTypes::Int32Type, "first_set32"); ctx->TruncInst(firstSet, LLVMTypes::Int32Type, "first_set32");
llvm::Value *firstSet32Smear = ctx->SmearUniform(firstSet32); llvm::Value *firstSet32Smear = ctx->SmearUniform(firstSet32);
// Now set the execution mask based on doing a vector compare of // Now set the execution mask based on doing a vector compare of
// these two // these two
llvm::Value *iterMask = llvm::Value *iterMask =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
firstSet32Smear, programIndex); firstSet32Smear, programIndex);
iterMask = ctx->I1VecToBoolVec(iterMask); iterMask = ctx->I1VecToBoolVec(iterMask);
@@ -2015,12 +2015,12 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
// Also update the bitvector of lanes left to turn off the bit for // Also update the bitvector of lanes left to turn off the bit for
// the lane we're about to run. // the lane we're about to run.
llvm::Value *setMask = llvm::Value *setMask =
ctx->BinaryOperator(llvm::Instruction::Shl, LLVMInt64(1), ctx->BinaryOperator(llvm::Instruction::Shl, LLVMInt64(1),
firstSet, "set_mask"); firstSet, "set_mask");
llvm::Value *notSetMask = ctx->NotOperator(setMask); llvm::Value *notSetMask = ctx->NotOperator(setMask);
llvm::Value *newRemaining = llvm::Value *newRemaining =
ctx->BinaryOperator(llvm::Instruction::And, remainingBits, ctx->BinaryOperator(llvm::Instruction::And, remainingBits,
notSetMask, "new_remaining"); notSetMask, "new_remaining");
ctx->StoreInst(newRemaining, maskBitsPtr); ctx->StoreInst(newRemaining, maskBitsPtr);
@@ -2046,7 +2046,7 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
// the loop that jumps to the end, see if there are any lanes left // the loop that jumps to the end, see if there are any lanes left
// to be processed. // to be processed.
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits"); llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
llvm::Value *nonZero = llvm::Value *nonZero =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
remainingBits, LLVMInt64(0), "remaining_ne_zero"); remainingBits, LLVMInt64(0), "remaining_ne_zero");
ctx->BranchInst(bbFindNext, bbDone, nonZero); ctx->BranchInst(bbFindNext, bbDone, nonZero);
@@ -2102,8 +2102,8 @@ ForeachActiveStmt::EstimateCost() const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// ForeachUniqueStmt // ForeachUniqueStmt
ForeachUniqueStmt::ForeachUniqueStmt(const char *iterName, Expr *e, ForeachUniqueStmt::ForeachUniqueStmt(const char *iterName, Expr *e,
Stmt *s, SourcePos pos) Stmt *s, SourcePos pos)
: Stmt(pos) { : Stmt(pos) {
sym = m->symbolTable->LookupVariable(iterName); sym = m->symbolTable->LookupVariable(iterName);
expr = e; expr = e;
@@ -2113,7 +2113,7 @@ ForeachUniqueStmt::ForeachUniqueStmt(const char *iterName, Expr *e,
void void
ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const { ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
// First, allocate local storage for the symbol that we'll use for the // First, allocate local storage for the symbol that we'll use for the
@@ -2167,7 +2167,7 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
llvm::VectorType *llvmExprType; llvm::VectorType *llvmExprType;
if (exprValue == NULL || if (exprValue == NULL ||
(exprType = expr->GetType()) == NULL || (exprType = expr->GetType()) == NULL ||
(llvmExprType = (llvmExprType =
llvm::dyn_cast<llvm::VectorType>(exprValue->getType())) == NULL) { llvm::dyn_cast<llvm::VectorType>(exprValue->getType())) == NULL) {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return; return;
@@ -2179,13 +2179,13 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
// Onward to find the first set of lanes to run the loop for // Onward to find the first set of lanes to run the loop for
ctx->BranchInst(bbFindNext); ctx->BranchInst(bbFindNext);
ctx->SetCurrentBasicBlock(bbFindNext); { ctx->SetCurrentBasicBlock(bbFindNext); {
// Load the bitmask of the lanes left to be processed // Load the bitmask of the lanes left to be processed
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits"); llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
// Find the index of the first set bit in the mask // Find the index of the first set bit in the mask
llvm::Function *ctlzFunc = llvm::Function *ctlzFunc =
m->module->getFunction("__count_trailing_zeros_i64"); m->module->getFunction("__count_trailing_zeros_i64");
Assert(ctlzFunc != NULL); Assert(ctlzFunc != NULL);
llvm::Value *firstSet = ctx->CallInst(ctlzFunc, NULL, remainingBits, llvm::Value *firstSet = ctx->CallInst(ctlzFunc, NULL, remainingBits,
@@ -2193,7 +2193,7 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
// And load the corresponding element value from the temporary // And load the corresponding element value from the temporary
// memory storing the value of the varying expr. // memory storing the value of the varying expr.
llvm::Value *uniqueValuePtr = llvm::Value *uniqueValuePtr =
ctx->GetElementPtrInst(exprMem, LLVMInt64(0), firstSet, exprPtrType, ctx->GetElementPtrInst(exprMem, LLVMInt64(0), firstSet, exprPtrType,
"unique_index_ptr"); "unique_index_ptr");
llvm::Value *uniqueValue = ctx->LoadInst(uniqueValuePtr, "unique_value"); llvm::Value *uniqueValue = ctx->LoadInst(uniqueValuePtr, "unique_value");
@@ -2215,16 +2215,16 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
llvm::Value *uniqueSmear = ctx->SmearUniform(uniqueValue, "unique_smear"); llvm::Value *uniqueSmear = ctx->SmearUniform(uniqueValue, "unique_smear");
llvm::Value *matchingLanes = NULL; llvm::Value *matchingLanes = NULL;
if (uniqueValue->getType()->isFloatingPointTy()) if (uniqueValue->getType()->isFloatingPointTy())
matchingLanes = matchingLanes =
ctx->CmpInst(llvm::Instruction::FCmp, llvm::CmpInst::FCMP_OEQ, ctx->CmpInst(llvm::Instruction::FCmp, llvm::CmpInst::FCMP_OEQ,
uniqueSmear, exprValue, "matching_lanes"); uniqueSmear, exprValue, "matching_lanes");
else else
matchingLanes = matchingLanes =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
uniqueSmear, exprValue, "matching_lanes"); uniqueSmear, exprValue, "matching_lanes");
matchingLanes = ctx->I1VecToBoolVec(matchingLanes); matchingLanes = ctx->I1VecToBoolVec(matchingLanes);
llvm::Value *loopMask = llvm::Value *loopMask =
ctx->BinaryOperator(llvm::Instruction::And, oldMask, matchingLanes, ctx->BinaryOperator(llvm::Instruction::And, oldMask, matchingLanes,
"foreach_unique_loop_mask"); "foreach_unique_loop_mask");
ctx->SetInternalMask(loopMask); ctx->SetInternalMask(loopMask);
@@ -2234,8 +2234,8 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
// remainingBits &= ~movmsk(current mask) // remainingBits &= ~movmsk(current mask)
llvm::Value *loopMaskMM = ctx->LaneMask(loopMask); llvm::Value *loopMaskMM = ctx->LaneMask(loopMask);
llvm::Value *notLoopMaskMM = ctx->NotOperator(loopMaskMM); llvm::Value *notLoopMaskMM = ctx->NotOperator(loopMaskMM);
llvm::Value *newRemaining = llvm::Value *newRemaining =
ctx->BinaryOperator(llvm::Instruction::And, remainingBits, ctx->BinaryOperator(llvm::Instruction::And, remainingBits,
notLoopMaskMM, "new_remaining"); notLoopMaskMM, "new_remaining");
ctx->StoreInst(newRemaining, maskBitsPtr); ctx->StoreInst(newRemaining, maskBitsPtr);
@@ -2260,7 +2260,7 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
// to be processed. // to be processed.
ctx->RestoreContinuedLanes(); ctx->RestoreContinuedLanes();
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits"); llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
llvm::Value *nonZero = llvm::Value *nonZero =
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
remainingBits, LLVMInt64(0), "remaining_ne_zero"); remainingBits, LLVMInt64(0), "remaining_ne_zero");
ctx->BranchInst(bbFindNext, bbDone, nonZero); ctx->BranchInst(bbFindNext, bbDone, nonZero);
@@ -2359,7 +2359,7 @@ lCheckMask(Stmt *stmts) {
} }
CaseStmt::CaseStmt(int v, Stmt *s, SourcePos pos) CaseStmt::CaseStmt(int v, Stmt *s, SourcePos pos)
: Stmt(pos), value(v) { : Stmt(pos), value(v) {
stmts = s; stmts = s;
} }
@@ -2397,7 +2397,7 @@ CaseStmt::EstimateCost() const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// DefaultStmt // DefaultStmt
DefaultStmt::DefaultStmt(Stmt *s, SourcePos pos) DefaultStmt::DefaultStmt(Stmt *s, SourcePos pos)
: Stmt(pos) { : Stmt(pos) {
stmts = s; stmts = s;
} }
@@ -2435,7 +2435,7 @@ DefaultStmt::EstimateCost() const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// SwitchStmt // SwitchStmt
SwitchStmt::SwitchStmt(Expr *e, Stmt *s, SourcePos pos) SwitchStmt::SwitchStmt(Expr *e, Stmt *s, SourcePos pos)
: Stmt(pos) { : Stmt(pos) {
expr = e; expr = e;
stmts = s; stmts = s;
@@ -2447,9 +2447,9 @@ SwitchStmt::SwitchStmt(Expr *e, Stmt *s, SourcePos pos)
structure to record all of the 'case' and 'default' statements after the structure to record all of the 'case' and 'default' statements after the
"switch". */ "switch". */
struct SwitchVisitInfo { struct SwitchVisitInfo {
SwitchVisitInfo(FunctionEmitContext *c) { SwitchVisitInfo(FunctionEmitContext *c) {
ctx = c; ctx = c;
defaultBlock = NULL; defaultBlock = NULL;
lastBlock = NULL; lastBlock = NULL;
} }
@@ -2491,11 +2491,11 @@ lSwitchASTPreVisit(ASTNode *node, void *d) {
// already // already
for (int i = 0; i < (int)svi->caseBlocks.size(); ++i) { for (int i = 0; i < (int)svi->caseBlocks.size(); ++i) {
if (svi->caseBlocks[i].first == cs->value) { if (svi->caseBlocks[i].first == cs->value) {
Error(cs->pos, "Duplicate case value \"%d\".", cs->value); Error(cs->pos, "Duplicate case value \"%d\".", cs->value);
return true; return true;
} }
} }
// Otherwise create a new basic block for the code following this // Otherwise create a new basic block for the code following this
// 'case' statement and record the mappign between the case label // 'case' statement and record the mappign between the case label
// value and the basic block // value and the basic block
@@ -2689,14 +2689,14 @@ UnmaskedStmt::EstimateCost() const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// ReturnStmt // ReturnStmt
ReturnStmt::ReturnStmt(Expr *e, SourcePos p) ReturnStmt::ReturnStmt(Expr *e, SourcePos p)
: Stmt(p), expr(e) { : Stmt(p), expr(e) {
} }
void void
ReturnStmt::EmitCode(FunctionEmitContext *ctx) const { ReturnStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
if (ctx->InForeachLoop()) { if (ctx->InForeachLoop()) {
@@ -2756,7 +2756,7 @@ ReturnStmt::Print(int indent) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// GotoStmt // GotoStmt
GotoStmt::GotoStmt(const char *l, SourcePos gotoPos, SourcePos ip) GotoStmt::GotoStmt(const char *l, SourcePos gotoPos, SourcePos ip)
: Stmt(gotoPos) { : Stmt(gotoPos) {
label = l; label = l;
identifierPos = ip; identifierPos = ip;
@@ -2765,7 +2765,7 @@ GotoStmt::GotoStmt(const char *l, SourcePos gotoPos, SourcePos ip)
void void
GotoStmt::EmitCode(FunctionEmitContext *ctx) const { GotoStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
if (ctx->VaryingCFDepth() > 0) { if (ctx->VaryingCFDepth() > 0) {
@@ -2793,7 +2793,7 @@ GotoStmt::EmitCode(FunctionEmitContext *ctx) const {
} }
/* Label wasn't found. Emit an error */ /* Label wasn't found. Emit an error */
Error(identifierPos, Error(identifierPos,
"No label named \"%s\" found in current function.%s", "No label named \"%s\" found in current function.%s",
label.c_str(), match_output.c_str()); label.c_str(), match_output.c_str());
@@ -2832,7 +2832,7 @@ GotoStmt::EstimateCost() const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// LabeledStmt // LabeledStmt
LabeledStmt::LabeledStmt(const char *n, Stmt *s, SourcePos p) LabeledStmt::LabeledStmt(const char *n, Stmt *s, SourcePos p)
: Stmt(p) { : Stmt(p) {
name = n; name = n;
stmt = s; stmt = s;
@@ -2934,7 +2934,7 @@ StmtList::Print(int indent) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// PrintStmt // PrintStmt
PrintStmt::PrintStmt(const std::string &f, Expr *v, SourcePos p) PrintStmt::PrintStmt(const std::string &f, Expr *v, SourcePos p)
: Stmt(p), format(f), values(v) { : Stmt(p), format(f), values(v) {
} }
@@ -2995,11 +2995,11 @@ lProcessPrintArg(Expr *expr, FunctionEmitContext *ctx, std::string &argTypes) {
Type::Equal(baseType, AtomicType::UniformInt16) || Type::Equal(baseType, AtomicType::UniformInt16) ||
Type::Equal(baseType, AtomicType::UniformUInt16)) { Type::Equal(baseType, AtomicType::UniformUInt16)) {
expr = new TypeCastExpr(type->IsUniformType() ? AtomicType::UniformInt32 : expr = new TypeCastExpr(type->IsUniformType() ? AtomicType::UniformInt32 :
AtomicType::VaryingInt32, AtomicType::VaryingInt32,
expr, expr->pos); expr, expr->pos);
type = expr->GetType(); type = expr->GetType();
} }
char t = lEncodeType(type->GetAsNonConstType()); char t = lEncodeType(type->GetAsNonConstType());
if (t == '\0') { if (t == '\0') {
Error(expr->pos, "Only atomic types are allowed in print statements; " Error(expr->pos, "Only atomic types are allowed in print statements; "
@@ -3030,7 +3030,7 @@ lProcessPrintArg(Expr *expr, FunctionEmitContext *ctx, std::string &argTypes) {
*/ */
void void
PrintStmt::EmitCode(FunctionEmitContext *ctx) const { PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
ctx->SetDebugPos(pos); ctx->SetDebugPos(pos);
@@ -3039,7 +3039,7 @@ PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
// in the code emitted below // in the code emitted below
// //
// 1. the format string // 1. the format string
// 2. a string encoding the types of the values being printed, // 2. a string encoding the types of the values being printed,
// one character per value // one character per value
// 3. the number of running program instances (i.e. the target's // 3. the number of running program instances (i.e. the target's
// vector width) // vector width)
@@ -3049,7 +3049,7 @@ PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
std::string argTypes; std::string argTypes;
if (values == NULL) { if (values == NULL) {
llvm::Type *ptrPtrType = llvm::Type *ptrPtrType =
llvm::PointerType::get(LLVMTypes::VoidPointerType, 0); llvm::PointerType::get(LLVMTypes::VoidPointerType, 0);
args[4] = llvm::Constant::getNullValue(ptrPtrType); args[4] = llvm::Constant::getNullValue(ptrPtrType);
} }
@@ -3060,14 +3060,14 @@ PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
ExprList *elist = dynamic_cast<ExprList *>(values); ExprList *elist = dynamic_cast<ExprList *>(values);
int nArgs = elist ? elist->exprs.size() : 1; int nArgs = elist ? elist->exprs.size() : 1;
// Allocate space for the array of pointers to values to be printed // Allocate space for the array of pointers to values to be printed
llvm::Type *argPtrArrayType = llvm::Type *argPtrArrayType =
llvm::ArrayType::get(LLVMTypes::VoidPointerType, nArgs); llvm::ArrayType::get(LLVMTypes::VoidPointerType, nArgs);
llvm::Value *argPtrArray = ctx->AllocaInst(argPtrArrayType, llvm::Value *argPtrArray = ctx->AllocaInst(argPtrArrayType,
"print_arg_ptrs"); "print_arg_ptrs");
// Store the array pointer as a void **, which is what __do_print() // Store the array pointer as a void **, which is what __do_print()
// expects // expects
args[4] = ctx->BitCastInst(argPtrArray, args[4] = ctx->BitCastInst(argPtrArray,
llvm::PointerType::get(LLVMTypes::VoidPointerType, 0)); llvm::PointerType::get(LLVMTypes::VoidPointerType, 0));
// Now, for each of the arguments, emit code to evaluate its value // Now, for each of the arguments, emit code to evaluate its value
@@ -3131,14 +3131,14 @@ PrintStmt::EstimateCost() const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// AssertStmt // AssertStmt
AssertStmt::AssertStmt(const std::string &msg, Expr *e, SourcePos p) AssertStmt::AssertStmt(const std::string &msg, Expr *e, SourcePos p)
: Stmt(p), message(msg), expr(e) { : Stmt(p), message(msg), expr(e) {
} }
void void
AssertStmt::EmitCode(FunctionEmitContext *ctx) const { AssertStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
const Type *type; const Type *type;
@@ -3151,14 +3151,14 @@ AssertStmt::EmitCode(FunctionEmitContext *ctx) const {
// The actual functionality to do the check and then handle falure is // The actual functionality to do the check and then handle falure is
// done via a builtin written in bitcode in builtins/util.m4. // done via a builtin written in bitcode in builtins/util.m4.
llvm::Function *assertFunc = llvm::Function *assertFunc =
isUniform ? m->module->getFunction("__do_assert_uniform") : isUniform ? m->module->getFunction("__do_assert_uniform") :
m->module->getFunction("__do_assert_varying"); m->module->getFunction("__do_assert_varying");
AssertPos(pos, assertFunc != NULL); AssertPos(pos, assertFunc != NULL);
char *errorString; char *errorString;
if (asprintf(&errorString, "%s:%d:%d: Assertion failed: %s", if (asprintf(&errorString, "%s:%d:%d: Assertion failed: %s",
pos.name, pos.first_line, pos.first_column, pos.name, pos.first_line, pos.first_column,
message.c_str()) == -1) { message.c_str()) == -1) {
Error(pos, "Fatal error when generating assert string: asprintf() " Error(pos, "Fatal error when generating assert string: asprintf() "
"unable to allocate memory!"); "unable to allocate memory!");
@@ -3191,8 +3191,8 @@ AssertStmt::TypeCheck() {
const Type *type; const Type *type;
if (expr && (type = expr->GetType()) != NULL) { if (expr && (type = expr->GetType()) != NULL) {
bool isUniform = type->IsUniformType(); bool isUniform = type->IsUniformType();
expr = TypeConvertExpr(expr, isUniform ? AtomicType::UniformBool : expr = TypeConvertExpr(expr, isUniform ? AtomicType::UniformBool :
AtomicType::VaryingBool, AtomicType::VaryingBool,
"\"assert\" statement"); "\"assert\" statement");
if (expr == NULL) if (expr == NULL)
return NULL; return NULL;
@@ -3218,7 +3218,7 @@ DeleteStmt::DeleteStmt(Expr *e, SourcePos p)
void void
DeleteStmt::EmitCode(FunctionEmitContext *ctx) const { DeleteStmt::EmitCode(FunctionEmitContext *ctx) const {
if (!ctx->GetCurrentBasicBlock()) if (!ctx->GetCurrentBasicBlock())
return; return;
const Type *exprType; const Type *exprType;

22
stmt.h
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file stmt.h /** @file stmt.h
@@ -84,8 +84,8 @@ public:
struct VariableDeclaration { struct VariableDeclaration {
VariableDeclaration(Symbol *s = NULL, Expr *i = NULL) { VariableDeclaration(Symbol *s = NULL, Expr *i = NULL) {
sym = s; init = i; sym = s; init = i;
} }
Symbol *sym; Symbol *sym;
Expr *init; Expr *init;
@@ -137,12 +137,12 @@ private:
'false' blocks. */ 'false' blocks. */
const bool doAllCheck; const bool doAllCheck;
void emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask, void emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
llvm::Value *test) const; llvm::Value *test) const;
void emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *test) const; void emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *test) const;
void emitMaskAllOn(FunctionEmitContext *ctx, void emitMaskAllOn(FunctionEmitContext *ctx,
llvm::Value *test, llvm::BasicBlock *bDone) const; llvm::Value *test, llvm::BasicBlock *bDone) const;
void emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask, void emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
llvm::Value *test, llvm::BasicBlock *bDone) const; llvm::Value *test, llvm::BasicBlock *bDone) const;
}; };
@@ -152,7 +152,7 @@ private:
*/ */
class DoStmt : public Stmt { class DoStmt : public Stmt {
public: public:
DoStmt(Expr *testExpr, Stmt *bodyStmts, bool doCoherentCheck, DoStmt(Expr *testExpr, Stmt *bodyStmts, bool doCoherentCheck,
SourcePos pos); SourcePos pos);
void EmitCode(FunctionEmitContext *ctx) const; void EmitCode(FunctionEmitContext *ctx) const;
@@ -227,9 +227,9 @@ public:
*/ */
class ForeachStmt : public Stmt { class ForeachStmt : public Stmt {
public: public:
ForeachStmt(const std::vector<Symbol *> &loopVars, ForeachStmt(const std::vector<Symbol *> &loopVars,
const std::vector<Expr *> &startExprs, const std::vector<Expr *> &startExprs,
const std::vector<Expr *> &endExprs, const std::vector<Expr *> &endExprs,
Stmt *bodyStatements, bool tiled, SourcePos pos); Stmt *bodyStatements, bool tiled, SourcePos pos);
void EmitCode(FunctionEmitContext *ctx) const; void EmitCode(FunctionEmitContext *ctx) const;
@@ -283,7 +283,7 @@ public:
}; };
/** /**
*/ */
class UnmaskedStmt : public Stmt { class UnmaskedStmt : public Stmt {
public: public:
@@ -493,7 +493,7 @@ public:
Expr *expr; Expr *expr;
}; };
extern Stmt *CreateForeachActiveStmt(Symbol *iterSym, Stmt *stmts, extern Stmt *CreateForeachActiveStmt(Symbol *iterSym, Stmt *stmts,
SourcePos pos); SourcePos pos);
#endif // ISPC_STMT_H #endif // ISPC_STMT_H

18
sym.cpp
View File

@@ -28,11 +28,11 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file sym.cpp /** @file sym.cpp
@brief file with definitions for symbol and symbol table classes. @brief file with definitions for symbol and symbol table classes.
*/ */
#include "sym.h" #include "sym.h"
@@ -43,8 +43,8 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Symbol // Symbol
Symbol::Symbol(const std::string &n, SourcePos p, const Type *t, Symbol::Symbol(const std::string &n, SourcePos p, const Type *t,
StorageClass sc) StorageClass sc)
: pos(p), name(n) { : pos(p), name(n) {
storagePtr = NULL; storagePtr = NULL;
function = exportedFunction = NULL; function = exportedFunction = NULL;
@@ -72,7 +72,7 @@ SymbolTable::~SymbolTable() {
void void
SymbolTable::PushScope() { SymbolTable::PushScope() {
SymbolMapType *sm; SymbolMapType *sm;
if (freeSymbolMaps.size() > 0) { if (freeSymbolMaps.size() > 0) {
sm = freeSymbolMaps.back(); sm = freeSymbolMaps.back();
@@ -87,7 +87,7 @@ SymbolTable::PushScope() {
void void
SymbolTable::PopScope() { SymbolTable::PopScope() {
Assert(variables.size() > 1); Assert(variables.size() > 1);
freeSymbolMaps.push_back(variables.back()); freeSymbolMaps.push_back(variables.back());
variables.pop_back(); variables.pop_back();
@@ -105,14 +105,14 @@ SymbolTable::AddVariable(Symbol *symbol) {
if (i == (int)variables.size()-1) { if (i == (int)variables.size()-1) {
// If a symbol of the same name was declared in the // If a symbol of the same name was declared in the
// same scope, it's an error. // same scope, it's an error.
Error(symbol->pos, "Ignoring redeclaration of symbol \"%s\".", Error(symbol->pos, "Ignoring redeclaration of symbol \"%s\".",
symbol->name.c_str()); symbol->name.c_str());
return false; return false;
} }
else { else {
// Otherwise it's just shadowing something else, which // Otherwise it's just shadowing something else, which
// is legal but dangerous.. // is legal but dangerous..
Warning(symbol->pos, Warning(symbol->pos,
"Symbol \"%s\" shadows symbol declared in outer scope.", "Symbol \"%s\" shadows symbol declared in outer scope.",
symbol->name.c_str()); symbol->name.c_str());
(*variables.back())[symbol->name] = symbol; (*variables.back())[symbol->name] = symbol;
@@ -308,7 +308,7 @@ SymbolTable::Print() {
for (iter = sm.begin(); iter != sm.end(); ++iter) { for (iter = sm.begin(); iter != sm.end(); ++iter) {
fprintf(stderr, "%*c", depth, ' '); fprintf(stderr, "%*c", depth, ' ');
Symbol *sym = iter->second; Symbol *sym = iter->second;
fprintf(stderr, "%s [%s]", sym->name.c_str(), fprintf(stderr, "%s [%s]", sym->name.c_str(),
sym->type->GetString().c_str()); sym->type->GetString().c_str());
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");

48
sym.h
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file sym.h /** @file sym.h
@@ -75,7 +75,7 @@ public:
location in memory.) */ location in memory.) */
llvm::Function *function; /*!< For symbols that represent functions, llvm::Function *function; /*!< For symbols that represent functions,
this stores the LLVM Function value for this stores the LLVM Function value for
the symbol once it has been created. */ the symbol once it has been created. */
llvm::Function *exportedFunction; llvm::Function *exportedFunction;
/*!< For symbols that represent functions with /*!< For symbols that represent functions with
'export' qualifiers, this points to the LLVM 'export' qualifiers, this points to the LLVM
@@ -91,18 +91,18 @@ public:
struct types. For cases like these, ConstExpr is NULL, struct types. For cases like these, ConstExpr is NULL,
though for all const symbols, the value pointed to by the though for all const symbols, the value pointed to by the
storagePtr member will be its constant value. (This storagePtr member will be its constant value. (This
messiness is due to needing an ispc ConstExpr for the early messiness is due to needing an ispc ConstExpr for the early
constant folding optimizations). */ constant folding optimizations). */
StorageClass storageClass;/*!< Records the storage class (if any) provided with the StorageClass storageClass;/*!< Records the storage class (if any) provided with the
symbol's declaration. */ symbol's declaration. */
int varyingCFDepth; /*!< This member records the number of levels of nested 'varying' int varyingCFDepth; /*!< This member records the number of levels of nested 'varying'
control flow within which the symbol was declared. Having control flow within which the symbol was declared. Having
this value available makes it possible to avoid performing this value available makes it possible to avoid performing
masked stores when modifying the symbol's value when the masked stores when modifying the symbol's value when the
store is done at the same 'varying' control flow depth as store is done at the same 'varying' control flow depth as
the one where the symbol was originally declared. */ the one where the symbol was originally declared. */
const Function *parentFunction; const Function *parentFunction;
/*!< For symbols that are parameters to functions or are /*!< For symbols that are parameters to functions or are
variables declared inside functions, this gives the variables declared inside functions, this gives the
function they're in. */ function they're in. */
}; };
@@ -130,7 +130,7 @@ public:
/** For each scope started by a call to SymbolTable::PushScope(), there /** For each scope started by a call to SymbolTable::PushScope(), there
must be a matching call to SymbolTable::PopScope() at the end of must be a matching call to SymbolTable::PopScope() at the end of
that scope. */ that scope. */
void PopScope(); void PopScope();
/** Adds the given variable symbol to the symbol table. /** Adds the given variable symbol to the symbol table.
@@ -147,7 +147,7 @@ public:
returning the first match found. returning the first match found.
@param name The name of the variable to be searched for. @param name The name of the variable to be searched for.
@return A pointer to the Symbol, if a match is found. NULL if no @return A pointer to the Symbol, if a match is found. NULL if no
Symbol with the given name is in the symbol table. */ Symbol with the given name is in the symbol table. */
Symbol *LookupVariable(const char *name); Symbol *LookupVariable(const char *name);
@@ -165,7 +165,7 @@ public:
be returned in the provided vector and it's up the the caller to be returned in the provided vector and it's up the the caller to
resolve which one (if any) to use. Returns true if any matches resolve which one (if any) to use. Returns true if any matches
were found. */ were found. */
bool LookupFunction(const char *name, bool LookupFunction(const char *name,
std::vector<Symbol *> *matches = NULL); std::vector<Symbol *> *matches = NULL);
/** Looks for a function with the given name and type /** Looks for a function with the given name and type
@@ -174,28 +174,28 @@ public:
@return pointer to matching Symbol; NULL if none is found. */ @return pointer to matching Symbol; NULL if none is found. */
Symbol *LookupFunction(const char *name, const FunctionType *type); Symbol *LookupFunction(const char *name, const FunctionType *type);
/** Returns all of the functions in the symbol table that match the given /** Returns all of the functions in the symbol table that match the given
predicate. predicate.
@param pred A unary predicate that returns true or false, given a Symbol @param pred A unary predicate that returns true or false, given a Symbol
pointer, based on whether the symbol should be included in the returned pointer, based on whether the symbol should be included in the returned
set of matches. It can either be a function, with signature set of matches. It can either be a function, with signature
<tt>bool pred(const Symbol *s)</tt>, or a unary predicate object with <tt>bool pred(const Symbol *s)</tt>, or a unary predicate object with
an <tt>bool operator()(const Symbol *)</tt> method. an <tt>bool operator()(const Symbol *)</tt> method.
@param matches Pointer to a vector in which to return the matching @param matches Pointer to a vector in which to return the matching
symbols. symbols.
*/ */
template <typename Predicate> template <typename Predicate>
void GetMatchingFunctions(Predicate pred, void GetMatchingFunctions(Predicate pred,
std::vector<Symbol *> *matches) const; std::vector<Symbol *> *matches) const;
/** Returns all of the variable symbols in the symbol table that match /** Returns all of the variable symbols in the symbol table that match
the given predicate. The predicate is defined as in the the given predicate. The predicate is defined as in the
GetMatchingFunctions() method. GetMatchingFunctions() method.
*/ */
template <typename Predicate> template <typename Predicate>
void GetMatchingVariables(Predicate pred, void GetMatchingVariables(Predicate pred,
std::vector<Symbol *> *matches) const; std::vector<Symbol *> *matches) const;
/** Adds the named type to the symbol table. This is used for both /** Adds the named type to the symbol table. This is used for both
@@ -210,7 +210,7 @@ public:
@param pos Position in source file where the type was named @param pos Position in source file where the type was named
@return true if the named type was successfully added. False if a type @return true if the named type was successfully added. False if a type
with the same name has already been defined. with the same name has already been defined.
*/ */
bool AddType(const char *name, const Type *type, SourcePos pos); bool AddType(const char *name, const Type *type, SourcePos pos);
@@ -248,7 +248,7 @@ public:
const Type *RandomType(); const Type *RandomType();
private: private:
std::vector<std::string> closestTypeMatch(const char *str, std::vector<std::string> closestTypeMatch(const char *str,
bool structsVsEnums) const; bool structsVsEnums) const;
/** This member variable holds one SymbolMap for each of the current /** This member variable holds one SymbolMap for each of the current
@@ -278,7 +278,7 @@ private:
template <typename Predicate> void template <typename Predicate> void
SymbolTable::GetMatchingFunctions(Predicate pred, SymbolTable::GetMatchingFunctions(Predicate pred,
std::vector<Symbol *> *matches) const { std::vector<Symbol *> *matches) const {
// Iterate through all function symbols and apply the given predicate. // Iterate through all function symbols and apply the given predicate.
// If it returns true, add the Symbol * to the provided vector. // If it returns true, add the Symbol * to the provided vector.
@@ -294,7 +294,7 @@ SymbolTable::GetMatchingFunctions(Predicate pred,
template <typename Predicate> void template <typename Predicate> void
SymbolTable::GetMatchingVariables(Predicate pred, SymbolTable::GetMatchingVariables(Predicate pred,
std::vector<Symbol *> *matches) const { std::vector<Symbol *> *matches) const {
for (unsigned int i = 0; i < variables.size(); ++i) { for (unsigned int i = 0; i < variables.size(); ++i) {
SymbolMapType &sm = *(variables[i]); SymbolMapType &sm = *(variables[i]);

View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
@@ -61,7 +61,7 @@ extern "C" {
extern void f_duf(float *result, double *a, float b); extern void f_duf(float *result, double *a, float b);
extern void f_di(float *result, double *a, int *b); extern void f_di(float *result, double *a, int *b);
extern void result(float *val); extern void result(float *val);
void ISPCLaunch(void **handlePtr, void *f, void *d, int); void ISPCLaunch(void **handlePtr, void *f, void *d, int);
void ISPCSync(void *handle); void ISPCSync(void *handle);
void *ISPCAlloc(void **handlePtr, int64_t size, int32_t alignment); void *ISPCAlloc(void **handlePtr, int64_t size, int32_t alignment);
@@ -141,7 +141,7 @@ int main(int argc, char *argv[]) {
f_di(returned_result, vdouble, vint2); f_di(returned_result, vdouble, vint2);
#else #else
#error "Unknown or unset TEST_SIG value" #error "Unknown or unset TEST_SIG value"
#endif #endif
float expected_result[64]; float expected_result[64];
memset(expected_result, 0, 64*sizeof(float)); memset(expected_result, 0, 64*sizeof(float));
@@ -155,7 +155,7 @@ int main(int argc, char *argv[]) {
return 1; return 1;
#else #else
printf("%s: value %d disagrees: returned %f [%a], expected %f [%a]\n", printf("%s: value %d disagrees: returned %f [%a], expected %f [%a]\n",
argv[0], i, returned_result[i], returned_result[i], argv[0], i, returned_result[i], returned_result[i],
expected_result[i], expected_result[i]); expected_result[i], expected_result[i]);
++errors; ++errors;
#endif // EXPECT_FAILURE #endif // EXPECT_FAILURE

238
type.cpp
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file type.cpp /** @file type.cpp
@@ -79,7 +79,7 @@ lShouldPrintName(const std::string &name) {
/** Utility routine to create a llvm DIArray type of the given number of /** Utility routine to create a llvm DIArray type of the given number of
the given element type. */ the given element type. */
static llvm::DIType static llvm::DIType
lCreateDIArray(llvm::DIType eltType, int count) { lCreateDIArray(llvm::DIType eltType, int count) {
int lowerBound = 0, upperBound = count-1; int lowerBound = 0, upperBound = count-1;
@@ -125,9 +125,9 @@ Variability::GetString() const {
std::string std::string
Variability::MangleString() const { Variability::MangleString() const {
switch (type) { switch (type) {
case Uniform: case Uniform:
return "un"; return "un";
case Varying: case Varying:
return "vy"; return "vy";
case SOA: { case SOA: {
char buf[32]; char buf[32];
@@ -189,11 +189,11 @@ const AtomicType *AtomicType::UniformDouble =
new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Uniform, false); new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Uniform, false);
const AtomicType *AtomicType::VaryingDouble = const AtomicType *AtomicType::VaryingDouble =
new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Varying, false); new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Varying, false);
const AtomicType *AtomicType::Void = const AtomicType *AtomicType::Void =
new AtomicType(TYPE_VOID, Variability::Uniform, false); new AtomicType(TYPE_VOID, Variability::Uniform, false);
AtomicType::AtomicType(BasicType bt, Variability v, bool ic) AtomicType::AtomicType(BasicType bt, Variability v, bool ic)
: Type(ATOMIC_TYPE), basicType(bt), variability(v), isConst(ic) { : Type(ATOMIC_TYPE), basicType(bt), variability(v), isConst(ic) {
asOtherConstType = NULL; asOtherConstType = NULL;
asUniformType = asVaryingType = NULL; asUniformType = asVaryingType = NULL;
@@ -255,14 +255,14 @@ AtomicType::IsBoolType() const {
bool bool
AtomicType::IsConstType() const { AtomicType::IsConstType() const {
return isConst; return isConst;
} }
const AtomicType * const AtomicType *
AtomicType::GetAsUnsignedType() const { AtomicType::GetAsUnsignedType() const {
if (IsUnsignedType() == true) if (IsUnsignedType() == true)
return this; return this;
if (IsIntType() == false) if (IsIntType() == false)
@@ -286,9 +286,9 @@ AtomicType::GetAsUnsignedType() const {
const AtomicType * const AtomicType *
AtomicType::GetAsConstType() const { AtomicType::GetAsConstType() const {
if (basicType == TYPE_VOID || isConst == true) if (basicType == TYPE_VOID || isConst == true)
return this; return this;
if (asOtherConstType == NULL) { if (asOtherConstType == NULL) {
asOtherConstType = new AtomicType(basicType, variability, true); asOtherConstType = new AtomicType(basicType, variability, true);
asOtherConstType->asOtherConstType = this; asOtherConstType->asOtherConstType = this;
@@ -299,7 +299,7 @@ AtomicType::GetAsConstType() const {
const AtomicType * const AtomicType *
AtomicType::GetAsNonConstType() const { AtomicType::GetAsNonConstType() const {
if (basicType == TYPE_VOID || isConst == false) if (basicType == TYPE_VOID || isConst == false)
return this; return this;
if (asOtherConstType == NULL) { if (asOtherConstType == NULL) {
@@ -429,7 +429,7 @@ AtomicType::Mangle() const {
std::string std::string
AtomicType::GetCDeclaration(const std::string &name) const { AtomicType::GetCDeclaration(const std::string &name) const {
std::string ret; std::string ret;
if (variability != Variability::Uniform && if (variability != Variability::Uniform &&
variability != Variability::SOA) { variability != Variability::SOA) {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return ret; return ret;
@@ -583,7 +583,7 @@ AtomicType::GetDIType(llvm::DIDescriptor scope) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// EnumType // EnumType
EnumType::EnumType(SourcePos p) EnumType::EnumType(SourcePos p)
: Type(ENUM_TYPE), pos(p) { : Type(ENUM_TYPE), pos(p) {
// name = "/* (anonymous) */"; // name = "/* (anonymous) */";
isConst = false; isConst = false;
@@ -591,7 +591,7 @@ EnumType::EnumType(SourcePos p)
} }
EnumType::EnumType(const char *n, SourcePos p) EnumType::EnumType(const char *n, SourcePos p)
: Type(ENUM_TYPE), pos(p), name(n) { : Type(ENUM_TYPE), pos(p), name(n) {
isConst = false; isConst = false;
variability = Variability(Variability::Unbound); variability = Variability(Variability::Unbound);
@@ -604,31 +604,31 @@ EnumType::GetVariability() const {
} }
bool bool
EnumType::IsBoolType() const { EnumType::IsBoolType() const {
return false; return false;
} }
bool bool
EnumType::IsFloatType() const { EnumType::IsFloatType() const {
return false; return false;
} }
bool bool
EnumType::IsIntType() const { EnumType::IsIntType() const {
return true; return true;
} }
bool bool
EnumType::IsUnsignedType() const { EnumType::IsUnsignedType() const {
return true; return true;
} }
bool bool
EnumType::IsConstType() const { EnumType::IsConstType() const {
return isConst; return isConst;
} }
@@ -724,7 +724,7 @@ EnumType::GetAsNonConstType() const {
} }
std::string std::string
EnumType::GetString() const { EnumType::GetString() const {
std::string ret; std::string ret;
if (isConst) ret += "const "; if (isConst) ret += "const ";
@@ -737,7 +737,7 @@ EnumType::GetString() const {
} }
std::string std::string
EnumType::Mangle() const { EnumType::Mangle() const {
Assert(variability != Variability::Unbound); Assert(variability != Variability::Unbound);
@@ -749,7 +749,7 @@ EnumType::Mangle() const {
} }
std::string std::string
EnumType::GetCDeclaration(const std::string &varName) const { EnumType::GetCDeclaration(const std::string &varName) const {
if (variability != Variability::Uniform && if (variability != Variability::Uniform &&
variability != Variability::SOA) { variability != Variability::SOA) {
@@ -798,7 +798,7 @@ EnumType::LLVMType(llvm::LLVMContext *ctx) const {
} }
llvm::DIType llvm::DIType
EnumType::GetDIType(llvm::DIDescriptor scope) const { EnumType::GetDIType(llvm::DIDescriptor scope) const {
std::vector<llvm::Value *> enumeratorDescriptors; std::vector<llvm::Value *> enumeratorDescriptors;
for (unsigned int i = 0; i < enumerators.size(); ++i) { for (unsigned int i = 0; i < enumerators.size(); ++i) {
@@ -807,11 +807,11 @@ EnumType::GetDIType(llvm::DIDescriptor scope) const {
int count = enumerators[i]->constValue->AsUInt32(&enumeratorValue); int count = enumerators[i]->constValue->AsUInt32(&enumeratorValue);
Assert(count == 1); Assert(count == 1);
llvm::Value *descriptor = llvm::Value *descriptor =
m->diBuilder->createEnumerator(enumerators[i]->name, enumeratorValue); m->diBuilder->createEnumerator(enumerators[i]->name, enumeratorValue);
enumeratorDescriptors.push_back(descriptor); enumeratorDescriptors.push_back(descriptor);
} }
llvm::DIArray elementArray = llvm::DIArray elementArray =
m->diBuilder->getOrCreateArray(enumeratorDescriptors); m->diBuilder->getOrCreateArray(enumeratorDescriptors);
llvm::DIFile diFile = pos.GetDIFile(); llvm::DIFile diFile = pos.GetDIFile();
@@ -867,11 +867,11 @@ EnumType::GetEnumerator(int i) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// PointerType // PointerType
PointerType *PointerType::Void = PointerType *PointerType::Void =
new PointerType(AtomicType::Void, Variability(Variability::Uniform), false); new PointerType(AtomicType::Void, Variability(Variability::Uniform), false);
PointerType::PointerType(const Type *t, Variability v, bool ic, bool is, PointerType::PointerType(const Type *t, Variability v, bool ic, bool is,
bool fr) bool fr)
: Type(POINTER_TYPE), variability(v), isConst(ic), isSlice(is), isFrozen(fr) { : Type(POINTER_TYPE), variability(v), isConst(ic), isSlice(is), isFrozen(fr) {
baseType = t; baseType = t;
@@ -1013,7 +1013,7 @@ PointerType::ResolveUnboundVariability(Variability v) const {
Assert(v != Variability::Unbound); Assert(v != Variability::Unbound);
Variability ptrVariability = (variability == Variability::Unbound) ? v : Variability ptrVariability = (variability == Variability::Unbound) ? v :
variability; variability;
const Type *resolvedBaseType = const Type *resolvedBaseType =
baseType->ResolveUnboundVariability(Variability::Uniform); baseType->ResolveUnboundVariability(Variability::Uniform);
return new PointerType(resolvedBaseType, ptrVariability, isConst, isSlice, return new PointerType(resolvedBaseType, ptrVariability, isConst, isSlice,
isFrozen); isFrozen);
@@ -1038,7 +1038,7 @@ PointerType::GetAsNonConstType() const {
} }
std::string std::string
PointerType::GetString() const { PointerType::GetString() const {
if (baseType == NULL) { if (baseType == NULL) {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
@@ -1114,7 +1114,7 @@ PointerType::LLVMType(llvm::LLVMContext *ctx) const {
if (isSlice) { if (isSlice) {
llvm::Type *types[2]; llvm::Type *types[2];
types[0] = GetAsNonSlice()->LLVMType(ctx); types[0] = GetAsNonSlice()->LLVMType(ctx);
switch (variability.type) { switch (variability.type) {
case Variability::Uniform: case Variability::Uniform:
types[1] = LLVMTypes::Int32Type; types[1] = LLVMTypes::Int32Type;
@@ -1140,7 +1140,7 @@ PointerType::LLVMType(llvm::LLVMContext *ctx) const {
case Variability::Uniform: { case Variability::Uniform: {
llvm::Type *ptype = NULL; llvm::Type *ptype = NULL;
const FunctionType *ftype = CastType<FunctionType>(baseType); const FunctionType *ftype = CastType<FunctionType>(baseType);
if (ftype != NULL) if (ftype != NULL)
ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx), 0); ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx), 0);
else { else {
if (baseType == AtomicType::Void) if (baseType == AtomicType::Void)
@@ -1177,11 +1177,11 @@ PointerType::GetDIType(llvm::DIDescriptor scope) const {
int ptrAlignBits = bitsSize; int ptrAlignBits = bitsSize;
switch (variability.type) { switch (variability.type) {
case Variability::Uniform: case Variability::Uniform:
return m->diBuilder->createPointerType(diTargetType, bitsSize, return m->diBuilder->createPointerType(diTargetType, bitsSize,
ptrAlignBits); ptrAlignBits);
case Variability::Varying: { case Variability::Varying: {
// emit them as an array of pointers // emit them as an array of pointers
llvm::DIType eltType = m->diBuilder->createPointerType(diTargetType, llvm::DIType eltType = m->diBuilder->createPointerType(diTargetType,
bitsSize, ptrAlignBits); bitsSize, ptrAlignBits);
return lCreateDIArray(eltType, g->target.vectorWidth); return lCreateDIArray(eltType, g->target.vectorWidth);
} }
@@ -1207,7 +1207,7 @@ const Type *SequentialType::GetElementType(int index) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// ArrayType // ArrayType
ArrayType::ArrayType(const Type *c, int a) ArrayType::ArrayType(const Type *c, int a)
: SequentialType(ARRAY_TYPE), child(c), numElements(a) { : SequentialType(ARRAY_TYPE), child(c), numElements(a) {
// 0 -> unsized array. // 0 -> unsized array.
Assert(numElements >= 0); Assert(numElements >= 0);
@@ -1239,25 +1239,25 @@ ArrayType::GetVariability() const {
bool bool
ArrayType::IsFloatType() const { ArrayType::IsFloatType() const {
return false; return false;
} }
bool bool
ArrayType::IsIntType() const { ArrayType::IsIntType() const {
return false; return false;
} }
bool bool
ArrayType::IsUnsignedType() const { ArrayType::IsUnsignedType() const {
return false; return false;
} }
bool bool
ArrayType::IsBoolType() const { ArrayType::IsBoolType() const {
return false; return false;
} }
@@ -1519,7 +1519,7 @@ ArrayType::SizeUnsizedArrays(const Type *type, Expr *initExpr) {
ExprList *el = dynamic_cast<ExprList *>(exprList->exprs[i]); ExprList *el = dynamic_cast<ExprList *>(exprList->exprs[i]);
if (el == NULL || el->exprs.size() != nextSize) { if (el == NULL || el->exprs.size() != nextSize) {
Error(Union(exprList->exprs[0]->pos, exprList->exprs[i]->pos), Error(Union(exprList->exprs[0]->pos, exprList->exprs[i]->pos),
"Inconsistent initializer expression list lengths " "Inconsistent initializer expression list lengths "
"make it impossible to size unsized array dimensions."); "make it impossible to size unsized array dimensions.");
return NULL; return NULL;
@@ -1537,7 +1537,7 @@ ArrayType::SizeUnsizedArrays(const Type *type, Expr *initExpr) {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// VectorType // VectorType
VectorType::VectorType(const AtomicType *b, int a) VectorType::VectorType(const AtomicType *b, int a)
: SequentialType(VECTOR_TYPE), base(b), numElements(a) { : SequentialType(VECTOR_TYPE), base(b), numElements(a) {
Assert(numElements > 0); Assert(numElements > 0);
Assert(base != NULL); Assert(base != NULL);
@@ -1546,37 +1546,37 @@ VectorType::VectorType(const AtomicType *b, int a)
Variability Variability
VectorType::GetVariability() const { VectorType::GetVariability() const {
return base->GetVariability(); return base->GetVariability();
} }
bool bool
VectorType::IsFloatType() const { VectorType::IsFloatType() const {
return base->IsFloatType(); return base->IsFloatType();
} }
bool bool
VectorType::IsIntType() const { VectorType::IsIntType() const {
return base->IsIntType(); return base->IsIntType();
} }
bool bool
VectorType::IsUnsignedType() const { VectorType::IsUnsignedType() const {
return base->IsUnsignedType(); return base->IsUnsignedType();
} }
bool bool
VectorType::IsBoolType() const { VectorType::IsBoolType() const {
return base->IsBoolType(); return base->IsBoolType();
} }
bool bool
VectorType::IsConstType() const { VectorType::IsConstType() const {
return base->IsConstType(); return base->IsConstType();
} }
@@ -1796,22 +1796,22 @@ lMangleStructName(const std::string &name, Variability variability) {
default: default:
FATAL("Unexpected variability in lMangleStructName()"); FATAL("Unexpected variability in lMangleStructName()");
} }
// And stuff the name at the end.... // And stuff the name at the end....
n += name; n += name;
return n; return n;
} }
StructType::StructType(const std::string &n, const llvm::SmallVector<const Type *, 8> &elts, StructType::StructType(const std::string &n, const llvm::SmallVector<const Type *, 8> &elts,
const llvm::SmallVector<std::string, 8> &en, const llvm::SmallVector<std::string, 8> &en,
const llvm::SmallVector<SourcePos, 8> &ep, const llvm::SmallVector<SourcePos, 8> &ep,
bool ic, Variability v, SourcePos p) bool ic, Variability v, SourcePos p)
: CollectionType(STRUCT_TYPE), name(n), elementTypes(elts), elementNames(en), : CollectionType(STRUCT_TYPE), name(n), elementTypes(elts), elementNames(en),
elementPositions(ep), variability(v), isConst(ic), pos(p) { elementPositions(ep), variability(v), isConst(ic), pos(p) {
oppositeConstStructType = NULL; oppositeConstStructType = NULL;
finalElementTypes.resize(elts.size(), NULL); finalElementTypes.resize(elts.size(), NULL);
if (variability != Variability::Unbound) { if (variability != Variability::Unbound) {
// For structs with non-unbound variability, we'll create the // For structs with non-unbound variability, we'll create the
// correspoing LLVM struct type now, if one hasn't been made // correspoing LLVM struct type now, if one hasn't been made
@@ -1875,37 +1875,37 @@ StructType::StructType(const std::string &n, const llvm::SmallVector<const Type
Variability Variability
StructType::GetVariability() const { StructType::GetVariability() const {
return variability; return variability;
} }
bool bool
StructType::IsBoolType() const { StructType::IsBoolType() const {
return false; return false;
} }
bool bool
StructType::IsFloatType() const { StructType::IsFloatType() const {
return false; return false;
} }
bool bool
StructType::IsIntType() const { StructType::IsIntType() const {
return false; return false;
} }
bool bool
StructType::IsUnsignedType() const { StructType::IsUnsignedType() const {
return false; return false;
} }
bool bool
StructType::IsConstType() const { StructType::IsConstType() const {
return isConst; return isConst;
} }
@@ -1917,7 +1917,7 @@ StructType::GetBaseType() const {
const StructType * const StructType *
StructType::GetAsVaryingType() const { StructType::GetAsVaryingType() const {
if (IsVaryingType()) if (IsVaryingType())
return this; return this;
else else
return new StructType(name, elementTypes, elementNames, elementPositions, return new StructType(name, elementTypes, elementNames, elementPositions,
@@ -1927,7 +1927,7 @@ StructType::GetAsVaryingType() const {
const StructType * const StructType *
StructType::GetAsUniformType() const { StructType::GetAsUniformType() const {
if (IsUniformType()) if (IsUniformType())
return this; return this;
else else
return new StructType(name, elementTypes, elementNames, elementPositions, return new StructType(name, elementTypes, elementNames, elementPositions,
@@ -1937,7 +1937,7 @@ StructType::GetAsUniformType() const {
const StructType * const StructType *
StructType::GetAsUnboundVariabilityType() const { StructType::GetAsUnboundVariabilityType() const {
if (HasUnboundVariability()) if (HasUnboundVariability())
return this; return this;
else else
return new StructType(name, elementTypes, elementNames, elementPositions, return new StructType(name, elementTypes, elementNames, elementPositions,
@@ -1981,7 +1981,7 @@ StructType::GetAsConstType() const {
else if (oppositeConstStructType != NULL) else if (oppositeConstStructType != NULL)
return oppositeConstStructType; return oppositeConstStructType;
else { else {
oppositeConstStructType = oppositeConstStructType =
new StructType(name, elementTypes, elementNames, elementPositions, new StructType(name, elementTypes, elementNames, elementPositions,
true, variability, pos); true, variability, pos);
oppositeConstStructType->oppositeConstStructType = this; oppositeConstStructType->oppositeConstStructType = this;
@@ -1997,7 +1997,7 @@ StructType::GetAsNonConstType() const {
else if (oppositeConstStructType != NULL) else if (oppositeConstStructType != NULL)
return oppositeConstStructType; return oppositeConstStructType;
else { else {
oppositeConstStructType = oppositeConstStructType =
new StructType(name, elementTypes, elementNames, elementPositions, new StructType(name, elementTypes, elementNames, elementPositions,
false, variability, pos); false, variability, pos);
oppositeConstStructType->oppositeConstStructType = this; oppositeConstStructType->oppositeConstStructType = this;
@@ -2115,9 +2115,9 @@ StructType::GetDIType(llvm::DIDescriptor scope) const {
llvm::DIFile diFile = elementPositions[i].GetDIFile(); llvm::DIFile diFile = elementPositions[i].GetDIFile();
int line = elementPositions[i].first_line; int line = elementPositions[i].first_line;
llvm::DIType fieldType = llvm::DIType fieldType =
m->diBuilder->createMemberType(scope, elementNames[i], diFile, m->diBuilder->createMemberType(scope, elementNames[i], diFile,
line, eltSize, eltAlign, line, eltSize, eltAlign,
currentSize, 0, eltType); currentSize, 0, eltType);
elementLLVMTypes.push_back(fieldType); elementLLVMTypes.push_back(fieldType);
@@ -2201,7 +2201,7 @@ StructType::checkIfCanBeSOA(const StructType *st) {
Error(st->elementPositions[i], "Unable to apply SOA conversion to " Error(st->elementPositions[i], "Unable to apply SOA conversion to "
"struct due to \"%s\" member \"%s\" with bound \"%s\" " "struct due to \"%s\" member \"%s\" with bound \"%s\" "
"variability.", eltType->GetString().c_str(), "variability.", eltType->GetString().c_str(),
st->elementNames[i].c_str(), st->elementNames[i].c_str(),
eltType->IsUniformType() ? "uniform" : "varying"); eltType->IsUniformType() ? "uniform" : "varying");
ok = false; ok = false;
} }
@@ -2219,9 +2219,9 @@ StructType::checkIfCanBeSOA(const StructType *st) {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// UndefinedStructType // UndefinedStructType
UndefinedStructType::UndefinedStructType(const std::string &n, UndefinedStructType::UndefinedStructType(const std::string &n,
const Variability var, bool ic, const Variability var, bool ic,
SourcePos p) SourcePos p)
: Type(UNDEFINED_STRUCT_TYPE), name(n), variability(var), isConst(ic), pos(p) { : Type(UNDEFINED_STRUCT_TYPE), name(n), variability(var), isConst(ic), pos(p) {
Assert(name != ""); Assert(name != "");
if (variability != Variability::Unbound) { if (variability != Variability::Unbound) {
@@ -2392,7 +2392,7 @@ UndefinedStructType::GetDIType(llvm::DIDescriptor scope) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// ReferenceType // ReferenceType
ReferenceType::ReferenceType(const Type *t) ReferenceType::ReferenceType(const Type *t)
: Type(REFERENCE_TYPE), targetType(t) { : Type(REFERENCE_TYPE), targetType(t) {
asOtherConstType = NULL; asOtherConstType = NULL;
} }
@@ -2404,7 +2404,7 @@ ReferenceType::GetVariability() const {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return Variability(Variability::Unbound); return Variability(Variability::Unbound);
} }
return targetType->GetVariability(); return targetType->GetVariability();
} }
@@ -2414,7 +2414,7 @@ ReferenceType::IsBoolType() const {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return false; return false;
} }
return targetType->IsBoolType(); return targetType->IsBoolType();
} }
@@ -2424,7 +2424,7 @@ ReferenceType::IsFloatType() const {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return false; return false;
} }
return targetType->IsFloatType(); return targetType->IsFloatType();
} }
@@ -2434,7 +2434,7 @@ ReferenceType::IsIntType() const {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return false; return false;
} }
return targetType->IsIntType(); return targetType->IsIntType();
} }
@@ -2444,7 +2444,7 @@ ReferenceType::IsUnsignedType() const {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return false; return false;
} }
return targetType->IsUnsignedType(); return targetType->IsUnsignedType();
} }
@@ -2480,7 +2480,7 @@ ReferenceType::GetAsVaryingType() const {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return NULL; return NULL;
} }
if (IsVaryingType()) if (IsVaryingType())
return this; return this;
return new ReferenceType(targetType->GetAsVaryingType()); return new ReferenceType(targetType->GetAsVaryingType());
} }
@@ -2492,7 +2492,7 @@ ReferenceType::GetAsUniformType() const {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return NULL; return NULL;
} }
if (IsUniformType()) if (IsUniformType())
return this; return this;
return new ReferenceType(targetType->GetAsUniformType()); return new ReferenceType(targetType->GetAsUniformType());
} }
@@ -2504,7 +2504,7 @@ ReferenceType::GetAsUnboundVariabilityType() const {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return NULL; return NULL;
} }
if (HasUnboundVariability()) if (HasUnboundVariability())
return this; return this;
return new ReferenceType(targetType->GetAsUnboundVariabilityType()); return new ReferenceType(targetType->GetAsUnboundVariabilityType());
} }
@@ -2525,7 +2525,7 @@ ReferenceType::ResolveUnboundVariability(Variability v) const {
} }
return new ReferenceType(targetType->ResolveUnboundVariability(v)); return new ReferenceType(targetType->ResolveUnboundVariability(v));
} }
const ReferenceType * const ReferenceType *
ReferenceType::GetAsConstType() const { ReferenceType::GetAsConstType() const {
@@ -2599,7 +2599,7 @@ ReferenceType::GetCDeclaration(const std::string &name) const {
if (at->GetElementCount() == 0) { if (at->GetElementCount() == 0) {
// emit unsized arrays as pointers to the base type.. // emit unsized arrays as pointers to the base type..
std::string ret; std::string ret;
ret += at->GetElementType()->GetAsNonConstType()->GetCDeclaration("") + ret += at->GetElementType()->GetAsNonConstType()->GetCDeclaration("") +
std::string(" *"); std::string(" *");
if (lShouldPrintName(name)) if (lShouldPrintName(name))
ret += name; ret += name;
@@ -2657,11 +2657,11 @@ ReferenceType::GetDIType(llvm::DIDescriptor scope) const {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// FunctionType // FunctionType
FunctionType::FunctionType(const Type *r, FunctionType::FunctionType(const Type *r,
const llvm::SmallVector<const Type *, 8> &a, const llvm::SmallVector<const Type *, 8> &a,
SourcePos p) SourcePos p)
: Type(FUNCTION_TYPE), isTask(false), isExported(false), isExternC(false), : Type(FUNCTION_TYPE), isTask(false), isExported(false), isExternC(false),
isUnmasked(false), returnType(r), paramTypes(a), isUnmasked(false), returnType(r), paramTypes(a),
paramNames(llvm::SmallVector<std::string, 8>(a.size(), "")), paramNames(llvm::SmallVector<std::string, 8>(a.size(), "")),
paramDefaults(llvm::SmallVector<Expr *, 8>(a.size(), NULL)), paramDefaults(llvm::SmallVector<Expr *, 8>(a.size(), NULL)),
paramPositions(llvm::SmallVector<SourcePos, 8>(a.size(), p)) { paramPositions(llvm::SmallVector<SourcePos, 8>(a.size(), p)) {
@@ -2672,15 +2672,15 @@ FunctionType::FunctionType(const Type *r,
FunctionType::FunctionType(const Type *r, FunctionType::FunctionType(const Type *r,
const llvm::SmallVector<const Type *, 8> &a, const llvm::SmallVector<const Type *, 8> &a,
const llvm::SmallVector<std::string, 8> &an, const llvm::SmallVector<std::string, 8> &an,
const llvm::SmallVector<Expr *, 8> &ad, const llvm::SmallVector<Expr *, 8> &ad,
const llvm::SmallVector<SourcePos, 8> &ap, const llvm::SmallVector<SourcePos, 8> &ap,
bool it, bool is, bool ec, bool ium) bool it, bool is, bool ec, bool ium)
: Type(FUNCTION_TYPE), isTask(it), isExported(is), isExternC(ec), : Type(FUNCTION_TYPE), isTask(it), isExported(is), isExternC(ec),
isUnmasked(ium), returnType(r), paramTypes(a), paramNames(an), isUnmasked(ium), returnType(r), paramTypes(a), paramNames(an),
paramDefaults(ad), paramPositions(ap) { paramDefaults(ad), paramPositions(ap) {
Assert(paramTypes.size() == paramNames.size() && Assert(paramTypes.size() == paramNames.size() &&
paramNames.size() == paramDefaults.size() && paramNames.size() == paramDefaults.size() &&
paramDefaults.size() == paramPositions.size()); paramDefaults.size() == paramPositions.size());
Assert(returnType != NULL); Assert(returnType != NULL);
@@ -2847,7 +2847,7 @@ FunctionType::GetCDeclaration(const std::string &fname) const {
// to print out for multidimensional arrays (i.e. "float foo[][4] " // to print out for multidimensional arrays (i.e. "float foo[][4] "
// versus "float (foo *)[4]"). // versus "float (foo *)[4]").
const PointerType *pt = CastType<PointerType>(type); const PointerType *pt = CastType<PointerType>(type);
if (pt != NULL && if (pt != NULL &&
CastType<ArrayType>(pt->GetBaseType()) != NULL) { CastType<ArrayType>(pt->GetBaseType()) != NULL) {
type = new ArrayType(pt->GetBaseType(), 0); type = new ArrayType(pt->GetBaseType(), 0);
} }
@@ -2883,10 +2883,10 @@ FunctionType::GetDIType(llvm::DIDescriptor scope) const {
retArgTypes.push_back(t->GetDIType(scope)); retArgTypes.push_back(t->GetDIType(scope));
} }
llvm::DIArray retArgTypesArray = llvm::DIArray retArgTypesArray =
m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(retArgTypes)); m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(retArgTypes));
llvm::DIType diType = llvm::DIType diType =
// FIXME: DIFile // FIXME: DIFile
m->diBuilder->createSubroutineType(llvm::DIFile(), retArgTypesArray); m->diBuilder->createSubroutineType(llvm::DIFile(), retArgTypesArray);
return diType; return diType;
} }
@@ -2906,7 +2906,7 @@ FunctionType::GetReturnTypeString() const {
ret += "extern \"C\" "; ret += "extern \"C\" ";
if (isUnmasked) if (isUnmasked)
ret += "unmasked "; ret += "unmasked ";
if (isSafe) if (isSafe)
ret += "/*safe*/ "; ret += "/*safe*/ ";
if (costOverride > 0) { if (costOverride > 0) {
char buf[32]; char buf[32];
@@ -2920,7 +2920,7 @@ FunctionType::GetReturnTypeString() const {
llvm::FunctionType * llvm::FunctionType *
FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const { FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
if (isTask == true) if (isTask == true)
Assert(removeMask == false); Assert(removeMask == false);
// Get the LLVM Type *s for the function arguments // Get the LLVM Type *s for the function arguments
@@ -2959,7 +2959,7 @@ FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
callTypes.push_back(LLVMTypes::Int32Type); // taskCount callTypes.push_back(LLVMTypes::Int32Type); // taskCount
} }
else else
// Otherwise we already have the types of the arguments // Otherwise we already have the types of the arguments
callTypes = llvmArgTypes; callTypes = llvmArgTypes;
if (returnType == NULL) { if (returnType == NULL) {
@@ -2976,30 +2976,30 @@ FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
const Type * const Type *
FunctionType::GetParameterType(int i) const { FunctionType::GetParameterType(int i) const {
Assert(i < (int)paramTypes.size()); Assert(i < (int)paramTypes.size());
return paramTypes[i]; return paramTypes[i];
} }
Expr * Expr *
FunctionType::GetParameterDefault(int i) const { FunctionType::GetParameterDefault(int i) const {
Assert(i < (int)paramDefaults.size()); Assert(i < (int)paramDefaults.size());
return paramDefaults[i]; return paramDefaults[i];
} }
const SourcePos & const SourcePos &
FunctionType::GetParameterSourcePos(int i) const { FunctionType::GetParameterSourcePos(int i) const {
Assert(i < (int)paramPositions.size()); Assert(i < (int)paramPositions.size());
return paramPositions[i]; return paramPositions[i];
} }
const std::string & const std::string &
FunctionType::GetParameterName(int i) const { FunctionType::GetParameterName(int i) const {
Assert(i < (int)paramNames.size()); Assert(i < (int)paramNames.size());
return paramNames[i]; return paramNames[i];
} }
@@ -3030,7 +3030,7 @@ lVectorConvert(const Type *type, SourcePos pos, const char *reason, int vecSize)
if (vt) { if (vt) {
if (vt->GetElementCount() != vecSize) { if (vt->GetElementCount() != vecSize) {
Error(pos, "Implicit conversion between from vector type " Error(pos, "Implicit conversion between from vector type "
"\"%s\" to vector type of length %d for %s is not possible.", "\"%s\" to vector type of length %d for %s is not possible.",
type->GetString().c_str(), vecSize, reason); type->GetString().c_str(), vecSize, reason);
return NULL; return NULL;
} }
@@ -3049,7 +3049,7 @@ lVectorConvert(const Type *type, SourcePos pos, const char *reason, int vecSize)
const Type * const Type *
Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char *reason, Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char *reason,
bool forceVarying, int vecSize) { bool forceVarying, int vecSize) {
Assert(reason != NULL); Assert(reason != NULL);
@@ -3080,9 +3080,9 @@ Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char
} }
// Are they both the same type? If so, we're done, QED. // Are they both the same type? If so, we're done, QED.
if (Type::Equal(t0, t1)) if (Type::Equal(t0, t1))
return t0; return t0;
// If they're function types, it's hopeless if they didn't match in the // If they're function types, it's hopeless if they didn't match in the
// Type::Equal() call above. Fail here so that we don't get into // Type::Equal() call above. Fail here so that we don't get into
// trouble calling GetAsConstType()... // trouble calling GetAsConstType()...
@@ -3125,7 +3125,7 @@ Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char
} }
const Type *t = MoreGeneralType(vt0->GetElementType(), vt1->GetElementType(), const Type *t = MoreGeneralType(vt0->GetElementType(), vt1->GetElementType(),
pos, reason, forceVarying); pos, reason, forceVarying);
if (!t) if (!t)
return NULL; return NULL;
// The 'more general' version of the two vector element types must // The 'more general' version of the two vector element types must
@@ -3140,9 +3140,9 @@ Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char
// promote the other one to a vector type. This will fail and // promote the other one to a vector type. This will fail and
// return NULL if t1 is e.g. an array type and it's illegal to have // return NULL if t1 is e.g. an array type and it's illegal to have
// a vector of it.. // a vector of it..
const Type *t = MoreGeneralType(vt0->GetElementType(), t1, pos, const Type *t = MoreGeneralType(vt0->GetElementType(), t1, pos,
reason, forceVarying); reason, forceVarying);
if (!t) if (!t)
return NULL; return NULL;
const AtomicType *at = CastType<AtomicType>(t); const AtomicType *at = CastType<AtomicType>(t);
@@ -3152,9 +3152,9 @@ Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char
else if (vt1) { else if (vt1) {
// As in the above case, see if we can promote t0 to make a vector // As in the above case, see if we can promote t0 to make a vector
// that matches vt1. // that matches vt1.
const Type *t = MoreGeneralType(t0, vt1->GetElementType(), pos, const Type *t = MoreGeneralType(t0, vt1->GetElementType(), pos,
reason, forceVarying); reason, forceVarying);
if (!t) if (!t)
return NULL; return NULL;
const AtomicType *at = CastType<AtomicType>(t); const AtomicType *at = CastType<AtomicType>(t);
@@ -3234,7 +3234,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
const AtomicType *ata = CastType<AtomicType>(a); const AtomicType *ata = CastType<AtomicType>(a);
const AtomicType *atb = CastType<AtomicType>(b); const AtomicType *atb = CastType<AtomicType>(b);
if (ata != NULL && atb != NULL) { if (ata != NULL && atb != NULL) {
return ((ata->basicType == atb->basicType) && return ((ata->basicType == atb->basicType) &&
(ata->GetVariability() == atb->GetVariability())); (ata->GetVariability() == atb->GetVariability()));
} }
@@ -3251,14 +3251,14 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
const ArrayType *arta = CastType<ArrayType>(a); const ArrayType *arta = CastType<ArrayType>(a);
const ArrayType *artb = CastType<ArrayType>(b); const ArrayType *artb = CastType<ArrayType>(b);
if (arta != NULL && artb != NULL) if (arta != NULL && artb != NULL)
return (arta->GetElementCount() == artb->GetElementCount() && return (arta->GetElementCount() == artb->GetElementCount() &&
lCheckTypeEquality(arta->GetElementType(), artb->GetElementType(), lCheckTypeEquality(arta->GetElementType(), artb->GetElementType(),
ignoreConst)); ignoreConst));
const VectorType *vta = CastType<VectorType>(a); const VectorType *vta = CastType<VectorType>(a);
const VectorType *vtb = CastType<VectorType>(b); const VectorType *vtb = CastType<VectorType>(b);
if (vta != NULL && vtb != NULL) if (vta != NULL && vtb != NULL)
return (vta->GetElementCount() == vtb->GetElementCount() && return (vta->GetElementCount() == vtb->GetElementCount() &&
lCheckTypeEquality(vta->GetElementType(), vtb->GetElementType(), lCheckTypeEquality(vta->GetElementType(), vtb->GetElementType(),
ignoreConst)); ignoreConst));
@@ -3272,7 +3272,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
if (a->GetVariability() != b->GetVariability()) if (a->GetVariability() != b->GetVariability())
return false; return false;
const std::string &namea = sta ? sta->GetStructName() : const std::string &namea = sta ? sta->GetStructName() :
usta->GetStructName(); usta->GetStructName();
const std::string &nameb = stb ? stb->GetStructName() : const std::string &nameb = stb ? stb->GetStructName() :
ustb->GetStructName(); ustb->GetStructName();
@@ -3285,7 +3285,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
return (pta->IsUniformType() == ptb->IsUniformType() && return (pta->IsUniformType() == ptb->IsUniformType() &&
pta->IsSlice() == ptb->IsSlice() && pta->IsSlice() == ptb->IsSlice() &&
pta->IsFrozenSlice() == ptb->IsFrozenSlice() && pta->IsFrozenSlice() == ptb->IsFrozenSlice() &&
lCheckTypeEquality(pta->GetBaseType(), ptb->GetBaseType(), lCheckTypeEquality(pta->GetBaseType(), ptb->GetBaseType(),
ignoreConst)); ignoreConst));
const ReferenceType *rta = CastType<ReferenceType>(a); const ReferenceType *rta = CastType<ReferenceType>(a);
@@ -3299,7 +3299,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
if (fta != NULL && ftb != NULL) { if (fta != NULL && ftb != NULL) {
// Both the return types and all of the argument types must match // Both the return types and all of the argument types must match
// for function types to match // for function types to match
if (!lCheckTypeEquality(fta->GetReturnType(), ftb->GetReturnType(), if (!lCheckTypeEquality(fta->GetReturnType(), ftb->GetReturnType(),
ignoreConst)) ignoreConst))
return false; return false;

70
type.h
View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file type.h /** @file type.h
@@ -53,17 +53,17 @@ class ConstExpr;
class StructType; class StructType;
/** Types may have uniform, varying, SOA, or unbound variability; this /** Types may have uniform, varying, SOA, or unbound variability; this
struct is used by Type implementations to record their variability. struct is used by Type implementations to record their variability.
*/ */
struct Variability { struct Variability {
enum VarType { Unbound, Uniform, Varying, SOA }; enum VarType { Unbound, Uniform, Varying, SOA };
Variability(VarType t = Unbound, int w = 0) : type(t), soaWidth(w) { } Variability(VarType t = Unbound, int w = 0) : type(t), soaWidth(w) { }
bool operator==(const Variability &v) const { bool operator==(const Variability &v) const {
return v.type == type && v.soaWidth == soaWidth; return v.type == type && v.soaWidth == soaWidth;
} }
bool operator!=(const Variability &v) const { bool operator!=(const Variability &v) const {
return v.type != type || v.soaWidth != soaWidth; return v.type != type || v.soaWidth != soaWidth;
} }
@@ -72,7 +72,7 @@ struct Variability {
std::string GetString() const; std::string GetString() const;
std::string MangleString() const; std::string MangleString() const;
VarType type; VarType type;
int soaWidth; int soaWidth;
}; };
@@ -122,19 +122,19 @@ public:
/** Returns true if the underlying type is either a pointer type */ /** Returns true if the underlying type is either a pointer type */
bool IsPointerType() const; bool IsPointerType() const;
/** Returns true if the underlying type is a array type */ /** Returns true if the underlying type is a array type */
bool IsArrayType() const; bool IsArrayType() const;
/** Returns true if the underlying type is a array type */ /** Returns true if the underlying type is a array type */
bool IsReferenceType() const; bool IsReferenceType() const;
/** Returns true if the underlying type is either a pointer or an array */ /** Returns true if the underlying type is either a pointer or an array */
bool IsVoidType() const; bool IsVoidType() const;
/** Returns true if this type is 'const'-qualified. */ /** Returns true if this type is 'const'-qualified. */
virtual bool IsConstType() const = 0; virtual bool IsConstType() const = 0;
/** Returns true if the underlying type is a float or integer type. */ /** Returns true if the underlying type is a float or integer type. */
bool IsNumericType() const { return IsFloatType() || IsIntType(); } bool IsNumericType() const { return IsFloatType() || IsIntType(); }
@@ -142,13 +142,13 @@ public:
virtual Variability GetVariability() const = 0; virtual Variability GetVariability() const = 0;
/** Returns true if the underlying type is uniform */ /** Returns true if the underlying type is uniform */
bool IsUniformType() const { bool IsUniformType() const {
return GetVariability() == Variability::Uniform; return GetVariability() == Variability::Uniform;
} }
/** Returns true if the underlying type is varying */ /** Returns true if the underlying type is varying */
bool IsVaryingType() const { bool IsVaryingType() const {
return GetVariability() == Variability::Varying; return GetVariability() == Variability::Varying;
} }
/** Returns true if the type is laid out in "structure of arrays" /** Returns true if the type is laid out in "structure of arrays"
@@ -161,8 +161,8 @@ public:
/** Returns true if the underlying type's uniform/varying-ness is /** Returns true if the underlying type's uniform/varying-ness is
unbound. */ unbound. */
bool HasUnboundVariability() const { bool HasUnboundVariability() const {
return GetVariability() == Variability::Unbound; return GetVariability() == Variability::Unbound;
} }
/* Returns a type wherein any elements of the original type and /* Returns a type wherein any elements of the original type and
@@ -196,7 +196,7 @@ public:
For all other types, just returns its own type. */ For all other types, just returns its own type. */
virtual const Type *GetReferenceTarget() const; virtual const Type *GetReferenceTarget() const;
/** Get a const version of this type. If it's already const, then the old /** Get a const version of this type. If it's already const, then the old
Type pointer is returned. */ Type pointer is returned. */
virtual const Type *GetAsConstType() const = 0; virtual const Type *GetAsConstType() const = 0;
@@ -244,7 +244,7 @@ public:
needed. needed.
@param reason String describing the context of why the general @param reason String describing the context of why the general
type is needed (e.g. "+ operator"). type is needed (e.g. "+ operator").
@param forceVarying If \c true, then make sure that the returned @param forceVarying If \c true, then make sure that the returned
type is "varying". type is "varying".
@param vecSize The vector size of the returned type. If non-zero, @param vecSize The vector size of the returned type. If non-zero,
the returned type will be a VectorType of the the returned type will be a VectorType of the
@@ -254,7 +254,7 @@ public:
@todo the vecSize and forceVarying parts of this should probably be @todo the vecSize and forceVarying parts of this should probably be
factored out and done separately in the cases when needed. factored out and done separately in the cases when needed.
*/ */
static const Type *MoreGeneralType(const Type *type0, const Type *type1, static const Type *MoreGeneralType(const Type *type0, const Type *type1,
SourcePos pos, const char *reason, SourcePos pos, const char *reason,
@@ -275,7 +275,7 @@ protected:
}; };
/** @brief AtomicType represents basic types like floats, ints, etc. /** @brief AtomicType represents basic types like floats, ints, etc.
AtomicTypes can be either uniform or varying. Unique instances of all AtomicTypes can be either uniform or varying. Unique instances of all
of the possible <tt>AtomicType</tt>s are available in the static members of the possible <tt>AtomicType</tt>s are available in the static members
@@ -313,7 +313,7 @@ public:
llvm::Type *LLVMType(llvm::LLVMContext *ctx) const; llvm::Type *LLVMType(llvm::LLVMContext *ctx) const;
llvm::DIType GetDIType(llvm::DIDescriptor scope) const; llvm::DIType GetDIType(llvm::DIDescriptor scope) const;
/** This enumerator records the basic types that AtomicTypes can be /** This enumerator records the basic types that AtomicTypes can be
built from. */ built from. */
enum BasicType { enum BasicType {
TYPE_VOID, TYPE_VOID,
@@ -431,7 +431,7 @@ private:
*/ */
class PointerType : public Type { class PointerType : public Type {
public: public:
PointerType(const Type *t, Variability v, bool isConst, PointerType(const Type *t, Variability v, bool isConst,
bool isSlice = false, bool frozen = false); bool isSlice = false, bool frozen = false);
/** Helper method to return a uniform pointer to the given type. */ /** Helper method to return a uniform pointer to the given type. */
@@ -488,7 +488,7 @@ private:
This is a common base class that StructTypes, ArrayTypes, and This is a common base class that StructTypes, ArrayTypes, and
VectorTypes all inherit from. VectorTypes all inherit from.
*/ */
class CollectionType : public Type { class CollectionType : public Type {
public: public:
/** Returns the total number of elements in the collection. */ /** Returns the total number of elements in the collection. */
@@ -532,7 +532,7 @@ protected:
ArrayType represents a one-dimensional array of instances of some other ArrayType represents a one-dimensional array of instances of some other
type. (Multi-dimensional arrays are represented by ArrayTypes that in type. (Multi-dimensional arrays are represented by ArrayTypes that in
turn hold ArrayTypes as their child types.) turn hold ArrayTypes as their child types.)
*/ */
class ArrayType : public SequentialType { class ArrayType : public SequentialType {
public: public:
@@ -592,7 +592,7 @@ public:
any array dimensions that are unsized according to the number of any array dimensions that are unsized according to the number of
elements in the corresponding sectoin of the initializer elements in the corresponding sectoin of the initializer
expression. expression.
*/ */
static const Type *SizeUnsizedArrays(const Type *type, Expr *initExpr); static const Type *SizeUnsizedArrays(const Type *type, Expr *initExpr);
private: private:
@@ -663,9 +663,9 @@ private:
*/ */
class StructType : public CollectionType { class StructType : public CollectionType {
public: public:
StructType(const std::string &name, const llvm::SmallVector<const Type *, 8> &elts, StructType(const std::string &name, const llvm::SmallVector<const Type *, 8> &elts,
const llvm::SmallVector<std::string, 8> &eltNames, const llvm::SmallVector<std::string, 8> &eltNames,
const llvm::SmallVector<SourcePos, 8> &eltPositions, bool isConst, const llvm::SmallVector<SourcePos, 8> &eltPositions, bool isConst,
Variability variability, SourcePos pos); Variability variability, SourcePos pos);
Variability GetVariability() const; Variability GetVariability() const;
@@ -707,7 +707,7 @@ public:
/** Returns the name of the i'th element of the structure. */ /** Returns the name of the i'th element of the structure. */
const std::string &GetElementName(int i) const { return elementNames[i]; } const std::string &GetElementName(int i) const { return elementNames[i]; }
/** Returns the total number of elements in the structure. */ /** Returns the total number of elements in the structure. */
int GetElementCount() const { return int(elementTypes.size()); } int GetElementCount() const { return int(elementTypes.size()); }
@@ -842,9 +842,9 @@ private:
*/ */
class FunctionType : public Type { class FunctionType : public Type {
public: public:
FunctionType(const Type *returnType, FunctionType(const Type *returnType,
const llvm::SmallVector<const Type *, 8> &argTypes, SourcePos pos); const llvm::SmallVector<const Type *, 8> &argTypes, SourcePos pos);
FunctionType(const Type *returnType, FunctionType(const Type *returnType,
const llvm::SmallVector<const Type *, 8> &argTypes, const llvm::SmallVector<const Type *, 8> &argTypes,
const llvm::SmallVector<std::string, 8> &argNames, const llvm::SmallVector<std::string, 8> &argNames,
const llvm::SmallVector<Expr *, 8> &argDefaults, const llvm::SmallVector<Expr *, 8> &argDefaults,
@@ -884,7 +884,7 @@ public:
function type. The \c disableMask parameter indicates whether the function type. The \c disableMask parameter indicates whether the
llvm::FunctionType should have the trailing mask parameter, if llvm::FunctionType should have the trailing mask parameter, if
present, removed from the return function signature. */ present, removed from the return function signature. */
llvm::FunctionType *LLVMFunctionType(llvm::LLVMContext *ctx, llvm::FunctionType *LLVMFunctionType(llvm::LLVMContext *ctx,
bool disableMask = false) const; bool disableMask = false) const;
int GetNumParameters() const { return (int)paramTypes.size(); } int GetNumParameters() const { return (int)paramTypes.size(); }
@@ -915,7 +915,7 @@ public:
bool isSafe; bool isSafe;
/** If non-negative, this provides a user-supplied override to the cost /** If non-negative, this provides a user-supplied override to the cost
function estimate for the function. */ function estimate for the function. */
int costOverride; int costOverride;
private: private:
@@ -993,7 +993,7 @@ template <> inline const SequentialType *
CastType(const Type *type) { CastType(const Type *type) {
// Note that this function must be updated if other sequential type // Note that this function must be updated if other sequential type
// implementations are added. // implementations are added.
if (type != NULL && if (type != NULL &&
(type->typeId == ARRAY_TYPE || type->typeId == VECTOR_TYPE)) (type->typeId == ARRAY_TYPE || type->typeId == VECTOR_TYPE))
return (const SequentialType *)type; return (const SequentialType *)type;
else else
@@ -1004,7 +1004,7 @@ template <> inline const CollectionType *
CastType(const Type *type) { CastType(const Type *type) {
// Similarly a new collection type implementation requires updating // Similarly a new collection type implementation requires updating
// this function. // this function.
if (type != NULL && if (type != NULL &&
(type->typeId == ARRAY_TYPE || type->typeId == VECTOR_TYPE || (type->typeId == ARRAY_TYPE || type->typeId == VECTOR_TYPE ||
type->typeId == STRUCT_TYPE)) type->typeId == STRUCT_TYPE))
return (const CollectionType *)type; return (const CollectionType *)type;

View File

@@ -28,7 +28,7 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file util.cpp /** @file util.cpp
@@ -139,7 +139,7 @@ lResetColor() {
} }
/** Given a pointer into a string, find the end of the current word and /** Given a pointer into a string, find the end of the current word and
return a pointer to its last character. return a pointer to its last character.
*/ */
static const char * static const char *
lFindWordEnd(const char *buf) { lFindWordEnd(const char *buf) {
@@ -166,7 +166,7 @@ lPrintFileLineContext(SourcePos p) {
while ((c = fgetc(f)) != EOF) { while ((c = fgetc(f)) != EOF) {
// Don't print more than three lines of context. (More than that, // Don't print more than three lines of context. (More than that,
// and we're probably doing the wrong thing...) // and we're probably doing the wrong thing...)
if (curLine >= std::max(p.first_line, p.last_line-2) && if (curLine >= std::max(p.first_line, p.last_line-2) &&
curLine <= p.last_line) curLine <= p.last_line)
fputc(c, stderr); fputc(c, stderr);
if (c == '\n') if (c == '\n')
@@ -322,7 +322,7 @@ asprintf(char **sptr, const char *fmt, ...)
@param args Arguments with values for format string % entries @param args Arguments with values for format string % entries
*/ */
static void static void
lPrint(const char *type, bool isError, SourcePos p, const char *fmt, lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
va_list args) { va_list args) {
char *errorBuf, *formattedBuf; char *errorBuf, *formattedBuf;
if (vasprintf(&errorBuf, fmt, args) == -1) { if (vasprintf(&errorBuf, fmt, args) == -1) {
@@ -335,7 +335,7 @@ lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
// We don't have a valid SourcePos, so create a message without it // We don't have a valid SourcePos, so create a message without it
if (asprintf(&formattedBuf, "%s%s%s%s%s: %s%s", lStartBold(), if (asprintf(&formattedBuf, "%s%s%s%s%s: %s%s", lStartBold(),
isError ? lStartRed() : lStartBlue(), type, isError ? lStartRed() : lStartBlue(), type,
lResetColor(), lStartBold(), errorBuf, lResetColor(), lStartBold(), errorBuf,
lResetColor()) == -1) { lResetColor()) == -1) {
fprintf(stderr, "asprintf() unable to allocate memory!\n"); fprintf(stderr, "asprintf() unable to allocate memory!\n");
exit(1); exit(1);
@@ -344,10 +344,10 @@ lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
} }
else { else {
// Create an error message that includes the file and line number // Create an error message that includes the file and line number
if (asprintf(&formattedBuf, "%s%s:%d:%d: %s%s%s%s: %s%s", if (asprintf(&formattedBuf, "%s%s:%d:%d: %s%s%s%s: %s%s",
lStartBold(), p.name, p.first_line, p.first_column, lStartBold(), p.name, p.first_line, p.first_column,
isError ? lStartRed() : lStartBlue(), type, isError ? lStartRed() : lStartBlue(), type,
lResetColor(), lStartBold(), errorBuf, lResetColor(), lStartBold(), errorBuf,
lResetColor()) == -1) { lResetColor()) == -1) {
fprintf(stderr, "asprintf() unable to allocate memory!\n"); fprintf(stderr, "asprintf() unable to allocate memory!\n");
exit(1); exit(1);
@@ -507,7 +507,7 @@ StringEditDistance(const std::string &str1, const std::string &str2, int maxDist
} }
std::vector<std::string> std::vector<std::string>
MatchStrings(const std::string &str, const std::vector<std::string> &options) { MatchStrings(const std::string &str, const std::vector<std::string> &options) {
if (str.size() == 0 || (str.size() == 1 && !isalpha(str[0]))) if (str.size() == 0 || (str.size() == 1 && !isalpha(str[0])))
// don't even try... // don't even try...
@@ -536,7 +536,7 @@ MatchStrings(const std::string &str, const std::vector<std::string> &options) {
void void
GetDirectoryAndFileName(const std::string &currentDirectory, GetDirectoryAndFileName(const std::string &currentDirectory,
const std::string &relativeName, const std::string &relativeName,
std::string *directory, std::string *filename) { std::string *directory, std::string *filename) {
#ifdef ISPC_IS_WINDOWS #ifdef ISPC_IS_WINDOWS
@@ -550,7 +550,7 @@ GetDirectoryAndFileName(const std::string &currentDirectory,
#else #else
// We need a fully qualified path. First, see if the current file name // We need a fully qualified path. First, see if the current file name
// is fully qualified itself--in that case, the current working // is fully qualified itself--in that case, the current working
// directory isn't needed. // directory isn't needed.
// @todo This probably needs to be smarter for Windows... // @todo This probably needs to be smarter for Windows...
std::string fullPath; std::string fullPath;
if (relativeName[0] == '/') if (relativeName[0] == '/')

16
util.h
View File

@@ -28,12 +28,12 @@
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file util.h /** @file util.h
@brief @brief
*/ */
#ifndef ISPC_UTIL_H #ifndef ISPC_UTIL_H
@@ -50,9 +50,9 @@ struct SourcePos;
of two already. */ of two already. */
inline uint32_t RoundUpPow2(uint32_t v) { inline uint32_t RoundUpPow2(uint32_t v) {
v--; v--;
v |= v >> 1; v |= v >> 1;
v |= v >> 2; v |= v >> 2;
v |= v >> 4; v |= v >> 4;
v |= v >> 8; v |= v >> 8;
v |= v >> 16; v |= v >> 16;
return v+1; return v+1;
@@ -75,7 +75,7 @@ int asprintf(char **sptr, const char *fmt, ...);
g->debugPrint is \c true. In addition to a program source code g->debugPrint is \c true. In addition to a program source code
position to associate with the message, a printf()-style format string position to associate with the message, a printf()-style format string
is passed along with any values needed for items in the format is passed along with any values needed for items in the format
string. string.
*/ */
void Debug(SourcePos p, const char *format, ...) PRINTF_FUNC; void Debug(SourcePos p, const char *format, ...) PRINTF_FUNC;
@@ -93,7 +93,7 @@ void Warning(SourcePos p, const char *format, ...) PRINTF_FUNC;
able to issue any subsequent error messages. In addition to a program able to issue any subsequent error messages. In addition to a program
source code position to associate with the message, a printf()-style source code position to associate with the message, a printf()-style
format string is passed along with any values needed for items in the format string is passed along with any values needed for items in the
format string. format string.
*/ */
void Error(SourcePos p, const char *format, ...) PRINTF_FUNC; void Error(SourcePos p, const char *format, ...) PRINTF_FUNC;
@@ -102,7 +102,7 @@ void Error(SourcePos p, const char *format, ...) PRINTF_FUNC;
completion of compilation. In addition to a program source code completion of compilation. In addition to a program source code
position to associate with the message, a printf()-style format string position to associate with the message, a printf()-style format string
is passed along with any values needed for items in the format is passed along with any values needed for items in the format
string. string.
*/ */
void PerformanceWarning(SourcePos p, const char *format, ...) PRINTF_FUNC; void PerformanceWarning(SourcePos p, const char *format, ...) PRINTF_FUNC;
@@ -143,7 +143,7 @@ std::vector<std::string> MatchStrings(const std::string &str,
/** Given the current working directory and a filename relative to that /** Given the current working directory and a filename relative to that
directory, this function returns the final directory that the resulting directory, this function returns the final directory that the resulting
file is in and the base name of the file itself. */ file is in and the base name of the file itself. */
void GetDirectoryAndFileName(const std::string &currentDir, void GetDirectoryAndFileName(const std::string &currentDir,
const std::string &relativeName, const std::string &relativeName,
std::string *directory, std::string *filename); std::string *directory, std::string *filename);