Editorial change: fixing trailing white spaces and tabs
This commit is contained in:
26
ast.cpp
26
ast.cpp
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -109,20 +109,20 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
|
||||
es->expr = (Expr *)WalkAST(es->expr, preFunc, postFunc, data);
|
||||
else if ((ds = dynamic_cast<DeclStmt *>(node)) != NULL) {
|
||||
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);
|
||||
}
|
||||
else if ((is = dynamic_cast<IfStmt *>(node)) != NULL) {
|
||||
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);
|
||||
is->falseStmts = (Stmt *)WalkAST(is->falseStmts, preFunc,
|
||||
is->falseStmts = (Stmt *)WalkAST(is->falseStmts, preFunc,
|
||||
postFunc, data);
|
||||
}
|
||||
else if ((dos = dynamic_cast<DoStmt *>(node)) != NULL) {
|
||||
dos->testExpr = (Expr *)WalkAST(dos->testExpr, preFunc,
|
||||
dos->testExpr = (Expr *)WalkAST(dos->testExpr, preFunc,
|
||||
postFunc, data);
|
||||
dos->bodyStmts = (Stmt *)WalkAST(dos->bodyStmts, preFunc,
|
||||
dos->bodyStmts = (Stmt *)WalkAST(dos->bodyStmts, preFunc,
|
||||
postFunc, data);
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
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);
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
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)
|
||||
aoe->expr = (Expr *)WalkAST(aoe->expr, preFunc, postFunc, data);
|
||||
else if ((newe = dynamic_cast<NewExpr *>(node)) != NULL) {
|
||||
newe->countExpr = (Expr *)WalkAST(newe->countExpr, preFunc,
|
||||
newe->countExpr = (Expr *)WalkAST(newe->countExpr, preFunc,
|
||||
postFunc, data);
|
||||
newe->initExpr = (Expr *)WalkAST(newe->initExpr, preFunc,
|
||||
newe->initExpr = (Expr *)WalkAST(newe->initExpr, preFunc,
|
||||
postFunc, data);
|
||||
}
|
||||
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<SyncExpr *>(node) != NULL ||
|
||||
dynamic_cast<NullPointerExpr *>(node) != NULL) {
|
||||
// nothing to do
|
||||
// nothing to do
|
||||
}
|
||||
else
|
||||
else
|
||||
FATAL("Unhandled expression type in WalkAST().");
|
||||
}
|
||||
|
||||
|
||||
10
ast.h
10
ast.h
@@ -28,11 +28,11 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@brief
|
||||
@brief
|
||||
*/
|
||||
|
||||
#ifndef ISPC_AST_H
|
||||
@@ -121,12 +121,12 @@ extern ASTNode *Optimize(ASTNode *root);
|
||||
|
||||
/** Convenience version of Optimize() for Expr *s that returns an Expr *
|
||||
(rather than an ASTNode *, which would require the caller to cast back
|
||||
to an Expr *). */
|
||||
to an Expr *). */
|
||||
extern Expr *Optimize(Expr *);
|
||||
|
||||
/** Convenience version of Optimize() for Expr *s that returns an Stmt *
|
||||
(rather than an ASTNode *, which would require the caller to cast back
|
||||
to a Stmt *). */
|
||||
to a Stmt *). */
|
||||
extern Stmt *Optimize(Stmt *);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** Returns true if it would be safe to run the given code with an "all
|
||||
off" mask. */
|
||||
off" mask. */
|
||||
extern bool SafeToRunWithMaskAllOff(ASTNode *root);
|
||||
|
||||
#endif // ISPC_AST_H
|
||||
|
||||
100
builtins.cpp
100
builtins.cpp
@@ -28,11 +28,11 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@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.
|
||||
*/
|
||||
|
||||
@@ -169,9 +169,9 @@ lLLVMTypeToISPCType(const llvm::Type *t, bool intAsUnsigned) {
|
||||
|
||||
|
||||
static void
|
||||
lCreateSymbol(const std::string &name, const Type *returnType,
|
||||
llvm::SmallVector<const Type *, 8> &argTypes,
|
||||
const llvm::FunctionType *ftype, llvm::Function *func,
|
||||
lCreateSymbol(const std::string &name, const Type *returnType,
|
||||
llvm::SmallVector<const Type *, 8> &argTypes,
|
||||
const llvm::FunctionType *ftype, llvm::Function *func,
|
||||
SymbolTable *symbolTable) {
|
||||
SourcePos noPos;
|
||||
noPos.name = "__stdlib";
|
||||
@@ -251,7 +251,7 @@ lCreateISPCSymbol(llvm::Function *func, SymbolTable *symbolTable) {
|
||||
"representable for builtin %s", j, name.c_str());
|
||||
return false;
|
||||
}
|
||||
anyIntArgs |=
|
||||
anyIntArgs |=
|
||||
(Type::Equal(type, lLLVMTypeToISPCType(llvmArgType, !intAsUnsigned)) == false);
|
||||
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
|
||||
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
|
||||
matches the signature of the actual intrinsic.
|
||||
*/
|
||||
@@ -304,7 +304,7 @@ lCheckModuleIntrinsics(llvm::Module *module) {
|
||||
if (!strncmp(funcName.c_str(), "llvm.x86.", 9)) {
|
||||
llvm::Intrinsic::ID id = (llvm::Intrinsic::ID)func->getIntrinsicID();
|
||||
Assert(id != 0);
|
||||
llvm::Type *intrinsicType =
|
||||
llvm::Type *intrinsicType =
|
||||
llvm::Intrinsic::getType(*g->ctx, id);
|
||||
intrinsicType = llvm::PointerType::get(intrinsicType, 0);
|
||||
Assert(func->getType() == intrinsicType);
|
||||
@@ -410,7 +410,7 @@ lSetInternalFunctions(llvm::Module *module) {
|
||||
"__delete_varying",
|
||||
"__do_assert_uniform",
|
||||
"__do_assert_varying",
|
||||
"__do_print",
|
||||
"__do_print",
|
||||
"__doublebits_uniform_int64",
|
||||
"__doublebits_varying_int64",
|
||||
"__exclusive_scan_add_double",
|
||||
@@ -654,7 +654,7 @@ AddBitcodeToModule(const unsigned char *bitcode, int length,
|
||||
bcModule->setDataLayout(module->getDataLayout());
|
||||
|
||||
std::string(linkError);
|
||||
if (llvm::Linker::LinkModules(module, bcModule,
|
||||
if (llvm::Linker::LinkModules(module, bcModule,
|
||||
llvm::Linker::DestroySource,
|
||||
&linkError))
|
||||
Error(SourcePos(), "Error linking stdlib bitcode: %s", linkError.c_str());
|
||||
@@ -672,7 +672,7 @@ AddBitcodeToModule(const unsigned char *bitcode, int length,
|
||||
static void
|
||||
lDefineConstantInt(const char *name, int val, llvm::Module *module,
|
||||
SymbolTable *symbolTable) {
|
||||
Symbol *sym =
|
||||
Symbol *sym =
|
||||
new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(),
|
||||
SC_STATIC);
|
||||
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
|
||||
// have the DW_AT_artifical attribute. It's not clear if this
|
||||
// matters for anything though.
|
||||
llvm::DIGlobalVariable var =
|
||||
m->diBuilder->createGlobalVariable(name,
|
||||
llvm::DIGlobalVariable var =
|
||||
m->diBuilder->createGlobalVariable(name,
|
||||
file,
|
||||
0 /* line */,
|
||||
diType,
|
||||
@@ -732,8 +732,8 @@ lDefineConstantIntFunc(const char *name, int val, llvm::Module *module,
|
||||
|
||||
static void
|
||||
lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) {
|
||||
Symbol *sym =
|
||||
new Symbol("programIndex", SourcePos(),
|
||||
Symbol *sym =
|
||||
new Symbol("programIndex", SourcePos(),
|
||||
AtomicType::VaryingInt32->GetAsConstType(), SC_STATIC);
|
||||
|
||||
int pi[ISPC_MAX_NVEC];
|
||||
@@ -755,7 +755,7 @@ lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) {
|
||||
llvm::DIType diType = sym->type->GetDIType(file);
|
||||
Assert(diType.Verify());
|
||||
llvm::DIGlobalVariable var =
|
||||
m->diBuilder->createGlobalVariable(sym->name.c_str(),
|
||||
m->diBuilder->createGlobalVariable(sym->name.c_str(),
|
||||
file,
|
||||
0 /* line */,
|
||||
diType,
|
||||
@@ -773,13 +773,13 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
||||
if (g->target.is32Bit) {
|
||||
extern unsigned char builtins_bitcode_c_32[];
|
||||
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);
|
||||
}
|
||||
else {
|
||||
extern unsigned char builtins_bitcode_c_64[];
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -792,12 +792,12 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
||||
extern unsigned char builtins_bitcode_sse2_x2[];
|
||||
extern int builtins_bitcode_sse2_x2_length;
|
||||
switch (g->target.vectorWidth) {
|
||||
case 4:
|
||||
AddBitcodeToModule(builtins_bitcode_sse2, builtins_bitcode_sse2_length,
|
||||
case 4:
|
||||
AddBitcodeToModule(builtins_bitcode_sse2, builtins_bitcode_sse2_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
case 8:
|
||||
AddBitcodeToModule(builtins_bitcode_sse2_x2, builtins_bitcode_sse2_x2_length,
|
||||
AddBitcodeToModule(builtins_bitcode_sse2_x2, builtins_bitcode_sse2_x2_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
default:
|
||||
@@ -810,14 +810,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
||||
extern unsigned char builtins_bitcode_sse4_x2[];
|
||||
extern int builtins_bitcode_sse4_x2_length;
|
||||
switch (g->target.vectorWidth) {
|
||||
case 4:
|
||||
case 4:
|
||||
AddBitcodeToModule(builtins_bitcode_sse4,
|
||||
builtins_bitcode_sse4_length,
|
||||
builtins_bitcode_sse4_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
case 8:
|
||||
AddBitcodeToModule(builtins_bitcode_sse4_x2,
|
||||
builtins_bitcode_sse4_x2_length,
|
||||
AddBitcodeToModule(builtins_bitcode_sse4_x2,
|
||||
builtins_bitcode_sse4_x2_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
default:
|
||||
@@ -829,14 +829,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
||||
case 8:
|
||||
extern unsigned char builtins_bitcode_avx1[];
|
||||
extern int builtins_bitcode_avx1_length;
|
||||
AddBitcodeToModule(builtins_bitcode_avx1,
|
||||
builtins_bitcode_avx1_length,
|
||||
AddBitcodeToModule(builtins_bitcode_avx1,
|
||||
builtins_bitcode_avx1_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
case 16:
|
||||
extern unsigned char builtins_bitcode_avx1_x2[];
|
||||
extern int builtins_bitcode_avx1_x2_length;
|
||||
AddBitcodeToModule(builtins_bitcode_avx1_x2,
|
||||
AddBitcodeToModule(builtins_bitcode_avx1_x2,
|
||||
builtins_bitcode_avx1_x2_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
@@ -849,14 +849,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
||||
case 8:
|
||||
extern unsigned char builtins_bitcode_avx11[];
|
||||
extern int builtins_bitcode_avx11_length;
|
||||
AddBitcodeToModule(builtins_bitcode_avx11,
|
||||
builtins_bitcode_avx11_length,
|
||||
AddBitcodeToModule(builtins_bitcode_avx11,
|
||||
builtins_bitcode_avx11_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
case 16:
|
||||
extern unsigned char builtins_bitcode_avx11_x2[];
|
||||
extern int builtins_bitcode_avx11_x2_length;
|
||||
AddBitcodeToModule(builtins_bitcode_avx11_x2,
|
||||
AddBitcodeToModule(builtins_bitcode_avx11_x2,
|
||||
builtins_bitcode_avx11_x2_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
@@ -869,14 +869,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
||||
case 8:
|
||||
extern unsigned char builtins_bitcode_avx2[];
|
||||
extern int builtins_bitcode_avx2_length;
|
||||
AddBitcodeToModule(builtins_bitcode_avx2,
|
||||
builtins_bitcode_avx2_length,
|
||||
AddBitcodeToModule(builtins_bitcode_avx2,
|
||||
builtins_bitcode_avx2_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
case 16:
|
||||
extern unsigned char builtins_bitcode_avx2_x2[];
|
||||
extern int builtins_bitcode_avx2_x2_length;
|
||||
AddBitcodeToModule(builtins_bitcode_avx2_x2,
|
||||
AddBitcodeToModule(builtins_bitcode_avx2_x2,
|
||||
builtins_bitcode_avx2_x2_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
@@ -889,43 +889,43 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
||||
case 4:
|
||||
extern unsigned char builtins_bitcode_generic_4[];
|
||||
extern int builtins_bitcode_generic_4_length;
|
||||
AddBitcodeToModule(builtins_bitcode_generic_4,
|
||||
builtins_bitcode_generic_4_length,
|
||||
AddBitcodeToModule(builtins_bitcode_generic_4,
|
||||
builtins_bitcode_generic_4_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
case 8:
|
||||
extern unsigned char builtins_bitcode_generic_8[];
|
||||
extern int builtins_bitcode_generic_8_length;
|
||||
AddBitcodeToModule(builtins_bitcode_generic_8,
|
||||
builtins_bitcode_generic_8_length,
|
||||
AddBitcodeToModule(builtins_bitcode_generic_8,
|
||||
builtins_bitcode_generic_8_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
case 16:
|
||||
extern unsigned char builtins_bitcode_generic_16[];
|
||||
extern int builtins_bitcode_generic_16_length;
|
||||
AddBitcodeToModule(builtins_bitcode_generic_16,
|
||||
builtins_bitcode_generic_16_length,
|
||||
AddBitcodeToModule(builtins_bitcode_generic_16,
|
||||
builtins_bitcode_generic_16_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
case 32:
|
||||
extern unsigned char builtins_bitcode_generic_32[];
|
||||
extern int builtins_bitcode_generic_32_length;
|
||||
AddBitcodeToModule(builtins_bitcode_generic_32,
|
||||
builtins_bitcode_generic_32_length,
|
||||
AddBitcodeToModule(builtins_bitcode_generic_32,
|
||||
builtins_bitcode_generic_32_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
case 64:
|
||||
extern unsigned char builtins_bitcode_generic_64[];
|
||||
extern int builtins_bitcode_generic_64_length;
|
||||
AddBitcodeToModule(builtins_bitcode_generic_64,
|
||||
builtins_bitcode_generic_64_length,
|
||||
AddBitcodeToModule(builtins_bitcode_generic_64,
|
||||
builtins_bitcode_generic_64_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
case 1:
|
||||
case 1:
|
||||
extern unsigned char builtins_bitcode_generic_1[];
|
||||
extern int builtins_bitcode_generic_1_length;
|
||||
AddBitcodeToModule(builtins_bitcode_generic_1,
|
||||
builtins_bitcode_generic_1_length,
|
||||
AddBitcodeToModule(builtins_bitcode_generic_1,
|
||||
builtins_bitcode_generic_1_length,
|
||||
module, symbolTable);
|
||||
break;
|
||||
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_ispc", (int)Globals::Math_ISPC, module,
|
||||
symbolTable);
|
||||
lDefineConstantInt("__math_lib_ispc_fast", (int)Globals::Math_ISPCFast,
|
||||
lDefineConstantInt("__math_lib_ispc_fast", (int)Globals::Math_ISPCFast,
|
||||
module, symbolTable);
|
||||
lDefineConstantInt("__math_lib_svml", (int)Globals::Math_SVML, module,
|
||||
symbolTable);
|
||||
@@ -956,9 +956,9 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
||||
lDefineConstantIntFunc("__fast_masked_vload", (int)g->opt.fastMaskedVload,
|
||||
module, symbolTable);
|
||||
|
||||
lDefineConstantInt("__have_native_half", g->target.hasHalf, module,
|
||||
lDefineConstantInt("__have_native_half", g->target.hasHalf, module,
|
||||
symbolTable);
|
||||
lDefineConstantInt("__have_native_rand", g->target.hasRand, module,
|
||||
lDefineConstantInt("__have_native_rand", g->target.hasRand, module,
|
||||
symbolTable);
|
||||
lDefineConstantInt("__have_native_transcendentals", g->target.hasTranscendentals,
|
||||
module, symbolTable);
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@brief Declarations of functions related to builtins and the
|
||||
@brief Declarations of functions related to builtins and the
|
||||
standard library
|
||||
*/
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -101,12 +101,12 @@ typedef int Bool;
|
||||
|
||||
@param format Print format string
|
||||
@param types Encoded types of the values being printed.
|
||||
(See lEncodeType()).
|
||||
(See lEncodeType()).
|
||||
@param width Vector width of the compilation target
|
||||
@param mask Current lane mask when the print statemnt is called
|
||||
@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) {
|
||||
char printString[PRINT_BUF_SIZE+1]; // +1 for trailing NUL
|
||||
char *bufp = &printString[0];
|
||||
|
||||
126
cbackend.cpp
126
cbackend.cpp
@@ -119,12 +119,12 @@ namespace {
|
||||
// objects, we keep several helper maps.
|
||||
llvm::DenseSet<const llvm::Value*> VisitedConstants;
|
||||
llvm::DenseSet<llvm::Type*> VisitedTypes;
|
||||
|
||||
|
||||
std::vector<llvm::ArrayType*> &ArrayTypes;
|
||||
public:
|
||||
TypeFinder(std::vector<llvm::ArrayType*> &t)
|
||||
: ArrayTypes(t) {}
|
||||
|
||||
|
||||
void run(const llvm::Module &M) {
|
||||
// Get types from global variables.
|
||||
for (llvm::Module::const_global_iterator I = M.global_begin(),
|
||||
@@ -133,7 +133,7 @@ namespace {
|
||||
if (I->hasInitializer())
|
||||
incorporateValue(I->getInitializer());
|
||||
}
|
||||
|
||||
|
||||
// Get types from aliases.
|
||||
for (llvm::Module::const_alias_iterator I = M.alias_begin(),
|
||||
E = M.alias_end(); I != E; ++I) {
|
||||
@@ -141,13 +141,13 @@ namespace {
|
||||
if (const llvm::Value *Aliasee = I->getAliasee())
|
||||
incorporateValue(Aliasee);
|
||||
}
|
||||
|
||||
|
||||
llvm::SmallVector<std::pair<unsigned, llvm::MDNode*>, 4> MDForInst;
|
||||
|
||||
// Get types from functions.
|
||||
for (llvm::Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
|
||||
incorporateType(FI->getType());
|
||||
|
||||
|
||||
for (llvm::Function::const_iterator BB = FI->begin(), E = FI->end();
|
||||
BB != E;++BB)
|
||||
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
|
||||
// want here. For now, punt on SwitchInsts.
|
||||
if (llvm::isa<llvm::SwitchInst>(&I)) continue;
|
||||
|
||||
|
||||
// Incorporate the type of the instruction and all its operands.
|
||||
incorporateType(I.getType());
|
||||
for (llvm::User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
|
||||
OI != OE; ++OI)
|
||||
incorporateValue(*OI);
|
||||
|
||||
|
||||
// Incorporate types hiding in metadata.
|
||||
I.getAllMetadataOtherThanDebugLoc(MDForInst);
|
||||
for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
|
||||
@@ -172,7 +172,7 @@ namespace {
|
||||
MDForInst.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(),
|
||||
E = M.named_metadata_end(); I != E; ++I) {
|
||||
const llvm::NamedMDNode *NMD = I;
|
||||
@@ -180,7 +180,7 @@ namespace {
|
||||
incorporateMDNode(NMD->getOperand(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void incorporateType(llvm::Type *Ty) {
|
||||
// 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))
|
||||
ArrayTypes.push_back(ATy);
|
||||
|
||||
|
||||
// Recursively walk all contained types.
|
||||
for (llvm::Type::subtype_iterator I = Ty->subtype_begin(),
|
||||
E = Ty->subtype_end(); I != E; ++I)
|
||||
incorporateType(*I);
|
||||
}
|
||||
|
||||
|
||||
/// incorporateValue - This method is used to walk operand lists finding
|
||||
/// types hiding in constant expressions and other operands that won't be
|
||||
/// 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))
|
||||
return incorporateMDNode(M);
|
||||
if (!llvm::isa<llvm::Constant>(V) || llvm::isa<llvm::GlobalValue>(V)) return;
|
||||
|
||||
|
||||
// Already visited?
|
||||
if (!VisitedConstants.insert(V).second)
|
||||
return;
|
||||
|
||||
|
||||
// Check this type.
|
||||
incorporateType(V->getType());
|
||||
|
||||
|
||||
// Look in operands for types.
|
||||
const llvm::User *U = llvm::cast<llvm::User>(V);
|
||||
for (llvm::Constant::const_op_iterator I = U->op_begin(),
|
||||
E = U->op_end(); I != E;++I)
|
||||
incorporateValue(*I);
|
||||
}
|
||||
|
||||
|
||||
void incorporateMDNode(const llvm::MDNode *V) {
|
||||
|
||||
|
||||
// Already visited?
|
||||
if (!VisitedConstants.insert(V).second)
|
||||
return;
|
||||
|
||||
|
||||
// Look in operands for types.
|
||||
for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i)
|
||||
if (llvm::Value *Op = V->getOperand(i))
|
||||
@@ -266,7 +266,7 @@ namespace {
|
||||
// TargetData have generally similar interfaces...
|
||||
const llvm::DataLayout* TD;
|
||||
#endif
|
||||
|
||||
|
||||
std::map<const llvm::ConstantFP *, unsigned> FPConstantMap;
|
||||
std::map<const llvm::ConstantDataVector *, unsigned> VectorConstantMap;
|
||||
unsigned VectorConstantIndex;
|
||||
@@ -276,7 +276,7 @@ namespace {
|
||||
unsigned OpaqueCounter;
|
||||
llvm::DenseMap<const llvm::Value*, unsigned> AnonValueNumbers;
|
||||
unsigned NextAnonValueNumber;
|
||||
|
||||
|
||||
std::string includeName;
|
||||
int vectorWidth;
|
||||
|
||||
@@ -291,7 +291,7 @@ namespace {
|
||||
int vecwidth)
|
||||
: FunctionPass(ID), Out(o), IL(0), /* Mang(0), */ LI(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"),
|
||||
vectorWidth(vecwidth) {
|
||||
initializeLoopInfoPass(*llvm::PassRegistry::getPassRegistry());
|
||||
@@ -372,7 +372,7 @@ namespace {
|
||||
|
||||
std::string getStructName(llvm::StructType *ST);
|
||||
std::string getArrayName(llvm::ArrayType *AT);
|
||||
|
||||
|
||||
/// writeOperandDeref - Print the result of dereferencing the specified
|
||||
/// operand with '*'. This is equivalent to printing '*' then using
|
||||
/// writeOperand, but avoids excess syntax in some cases.
|
||||
@@ -399,7 +399,7 @@ namespace {
|
||||
|
||||
private :
|
||||
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.
|
||||
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) {
|
||||
if (!ST->isLiteral() && !ST->getName().empty())
|
||||
return CBEMangle("l_"+ST->getName().str());
|
||||
|
||||
|
||||
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());
|
||||
switch (eltTy->getPrimitiveSizeInBits()) {
|
||||
case 1:
|
||||
suffix = "i1";
|
||||
suffix = "i1";
|
||||
break;
|
||||
case 8:
|
||||
suffix = "i8";
|
||||
suffix = "i8";
|
||||
break;
|
||||
case 16:
|
||||
suffix = "i16";
|
||||
suffix = "i16";
|
||||
break;
|
||||
case 32:
|
||||
suffix = "i32";
|
||||
suffix = "i32";
|
||||
break;
|
||||
case 64:
|
||||
suffix = "i64";
|
||||
suffix = "i64";
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
#else
|
||||
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,
|
||||
bool isSigned, const std::string &NameSoFar,
|
||||
bool IgnoreName,
|
||||
bool IgnoreName,
|
||||
#if defined(LLVM_3_1) || defined(LLVM_3_2)
|
||||
const llvm::AttrListPtr &PAL
|
||||
#else
|
||||
@@ -803,11 +803,11 @@ llvm::raw_ostream &CWriter::printType(llvm::raw_ostream &Out, llvm::Type *Ty,
|
||||
}
|
||||
case llvm::Type::StructTyID: {
|
||||
llvm::StructType *STy = llvm::cast<llvm::StructType>(Ty);
|
||||
|
||||
|
||||
// Check to see if the type is named.
|
||||
if (!IgnoreName)
|
||||
return Out << getStructName(STy) << ' ' << NameSoFar;
|
||||
|
||||
|
||||
Out << "struct " << NameSoFar << " {\n";
|
||||
|
||||
// print initialization func
|
||||
@@ -930,13 +930,13 @@ void CWriter::printConstantDataSequential(llvm::ConstantDataSequential *CDS,
|
||||
Out << '\"';
|
||||
// Keep track of whether the last number was a hexadecimal escape.
|
||||
bool LastWasHex = false;
|
||||
|
||||
|
||||
llvm::StringRef Bytes = CDS->getAsCString();
|
||||
|
||||
|
||||
// Do not include the last character, which we know is null
|
||||
for (unsigned i = 0, e = Bytes.size(); i != e; ++i) {
|
||||
unsigned char C = Bytes[i];
|
||||
|
||||
|
||||
// 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
|
||||
// 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
|
||||
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
|
||||
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
|
||||
string "__foo_i32<__vec16_i32>".
|
||||
*/
|
||||
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)) {
|
||||
printConstantArray(CA, Static);
|
||||
} else if (llvm::ConstantDataSequential *CDS =
|
||||
} else if (llvm::ConstantDataSequential *CDS =
|
||||
llvm::dyn_cast<llvm::ConstantDataSequential>(CPV)) {
|
||||
printConstantDataSequential(CDS, Static);
|
||||
} else {
|
||||
@@ -1584,7 +1584,7 @@ void CWriter::printConstant(llvm::Constant *CPV, bool Static) {
|
||||
llvm::report_fatal_error("Unexpected vector type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case llvm::Type::StructTyID:
|
||||
@@ -2658,7 +2658,7 @@ void CWriter::printModuleTypes() {
|
||||
Out << "/* Structure and array forward declarations */\n";
|
||||
|
||||
unsigned NextTypeID = 0;
|
||||
|
||||
|
||||
// If any of them are missing names, add a unique ID to UnnamedStructIDs.
|
||||
// Print out forward declarations for structure types.
|
||||
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)) {
|
||||
// Check to see if we have already printed this struct.
|
||||
if (!Printed.insert(Ty)) return;
|
||||
|
||||
|
||||
// Print structure type out.
|
||||
printType(Out, ST, false, getStructName(ST), true);
|
||||
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 << " return r;\n}\n";
|
||||
break;
|
||||
|
||||
case llvm::Intrinsic::sadd_with_overflow:
|
||||
|
||||
case llvm::Intrinsic::sadd_with_overflow:
|
||||
// static inline Rty sadd_ixx(ixx a, ixx b) {
|
||||
// Rty r;
|
||||
// r.field1 = (b > 0 && a > XX_MAX - b) ||
|
||||
@@ -3851,10 +3851,10 @@ void CWriter::visitCallInst(llvm::CallInst &I) {
|
||||
Out << ')';
|
||||
}
|
||||
// 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)
|
||||
llvm::Attributes::ByVal
|
||||
#else
|
||||
#else
|
||||
llvm::Attribute::ByVal
|
||||
#endif
|
||||
))
|
||||
@@ -4419,7 +4419,7 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
||||
|
||||
restart:
|
||||
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);
|
||||
if (insertInst == NULL)
|
||||
continue;
|
||||
@@ -4444,7 +4444,7 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
||||
else if (toMatch != insertValue)
|
||||
goto not_equal;
|
||||
|
||||
insertInst =
|
||||
insertInst =
|
||||
llvm::dyn_cast<llvm::InsertElementInst>(insertInst->getOperand(0));
|
||||
}
|
||||
assert(toMatch != NULL);
|
||||
@@ -4458,8 +4458,8 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
||||
// Declare the smear function if needed; it takes a single
|
||||
// scalar parameter and returns a vector of the same
|
||||
// parameter type.
|
||||
llvm::Constant *sf =
|
||||
module->getOrInsertFunction(smearFuncName, iter->getType(),
|
||||
llvm::Constant *sf =
|
||||
module->getOrInsertFunction(smearFuncName, iter->getType(),
|
||||
matchType, NULL);
|
||||
smearFunc = llvm::dyn_cast<llvm::Function>(sf);
|
||||
assert(smearFunc != NULL);
|
||||
@@ -4475,7 +4475,7 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
||||
assert(smearFunc != NULL);
|
||||
llvm::Value *args[1] = { toMatch };
|
||||
llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[1]);
|
||||
llvm::Instruction *smearCall =
|
||||
llvm::Instruction *smearCall =
|
||||
llvm::CallInst::Create(smearFunc, argArray, LLVMGetName(toMatch, "_smear"),
|
||||
(llvm::Instruction *)NULL);
|
||||
|
||||
@@ -4608,9 +4608,9 @@ AndCmpCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
||||
// are the same as the two arguments to the compare we're
|
||||
// replacing and the third argument is the mask type.
|
||||
llvm::Type *cmpOpType = opCmp->getOperand(0)->getType();
|
||||
llvm::Constant *acf =
|
||||
llvm::Constant *acf =
|
||||
m->module->getOrInsertFunction(funcName, LLVMTypes::MaskType,
|
||||
cmpOpType, cmpOpType,
|
||||
cmpOpType, cmpOpType,
|
||||
LLVMTypes::MaskType, NULL);
|
||||
andCmpFunc = llvm::dyn_cast<llvm::Function>(acf);
|
||||
Assert(andCmpFunc != NULL);
|
||||
@@ -4625,11 +4625,11 @@ AndCmpCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
||||
|
||||
// Set up the function call to the *_and_mask function; the
|
||||
// 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) };
|
||||
llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[3]);
|
||||
llvm::Instruction *cmpCall =
|
||||
llvm::CallInst::Create(andCmpFunc, argArray,
|
||||
llvm::Instruction *cmpCall =
|
||||
llvm::CallInst::Create(andCmpFunc, argArray,
|
||||
LLVMGetName(bop, "_and_mask"),
|
||||
(llvm::Instruction *)NULL);
|
||||
|
||||
@@ -4656,12 +4656,12 @@ AndCmpCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
||||
class MaskOpsCleanupPass : public llvm::BasicBlockPass {
|
||||
public:
|
||||
MaskOpsCleanupPass(llvm::Module *m)
|
||||
: BasicBlockPass(ID) {
|
||||
: BasicBlockPass(ID) {
|
||||
llvm::Type *mt = LLVMTypes::MaskType;
|
||||
|
||||
// Declare the __not, __and_not1, and __and_not2 functions that we
|
||||
// expect the target to end up providing.
|
||||
notFunc =
|
||||
notFunc =
|
||||
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__not", mt, mt, NULL));
|
||||
assert(notFunc != NULL);
|
||||
#if defined(LLVM_3_2)
|
||||
@@ -4672,7 +4672,7 @@ public:
|
||||
notFunc->addFnAttr(llvm::Attribute::ReadNone);
|
||||
#endif
|
||||
|
||||
andNotFuncs[0] =
|
||||
andNotFuncs[0] =
|
||||
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not1", mt, mt, mt,
|
||||
NULL));
|
||||
assert(andNotFuncs[0] != NULL);
|
||||
@@ -4683,7 +4683,7 @@ public:
|
||||
andNotFuncs[0]->addFnAttr(llvm::Attribute::NoUnwind);
|
||||
andNotFuncs[0]->addFnAttr(llvm::Attribute::ReadNone);
|
||||
#endif
|
||||
andNotFuncs[1] =
|
||||
andNotFuncs[1] =
|
||||
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not2", mt, mt, mt,
|
||||
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
|
||||
i1s with all elements 'true'.
|
||||
i1s with all elements 'true'.
|
||||
*/
|
||||
static bool
|
||||
lIsAllTrue(llvm::Value *v) {
|
||||
@@ -4721,7 +4721,7 @@ lIsAllTrue(llvm::Value *v) {
|
||||
(ci = llvm::dyn_cast<llvm::ConstantInt>(cv->getSplatValue())) != NULL &&
|
||||
ci->isOne());
|
||||
}
|
||||
|
||||
|
||||
if (llvm::ConstantDataVector *cdv = llvm::dyn_cast<llvm::ConstantDataVector>(v)) {
|
||||
llvm::ConstantInt *ci;
|
||||
return (cdv->getSplatValue() != NULL &&
|
||||
@@ -4770,7 +4770,7 @@ MaskOpsCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
||||
// Check for XOR with all-true values
|
||||
if (lIsAllTrue(bop->getOperand(1))) {
|
||||
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());
|
||||
ReplaceInstWithInst(iter, notCall);
|
||||
modifiedAny = true;
|
||||
@@ -4791,7 +4791,7 @@ MaskOpsCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
||||
llvm::ArrayRef<llvm::Value *> argsRef(&args[0], 2);
|
||||
|
||||
// Call the appropriate __and_not* function.
|
||||
llvm::CallInst *andNotCall =
|
||||
llvm::CallInst *andNotCall =
|
||||
llvm::CallInst::Create(andNotFuncs[i], argsRef, bop->getName());
|
||||
|
||||
ReplaceInstWithInst(iter, andNotCall);
|
||||
|
||||
54
ctx.h
54
ctx.h
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
@param firstStmtPos Source file position of the first statement in the
|
||||
function
|
||||
*/
|
||||
FunctionEmitContext(Function *function, Symbol *funSym,
|
||||
FunctionEmitContext(Function *function, Symbol *funSym,
|
||||
llvm::Function *llvmFunction,
|
||||
SourcePos firstStmtPos);
|
||||
~FunctionEmitContext();
|
||||
@@ -87,9 +87,9 @@ public:
|
||||
/** @name Current basic block management
|
||||
@{
|
||||
*/
|
||||
/** Returns the current basic block pointer */
|
||||
/** Returns the current basic block pointer */
|
||||
llvm::BasicBlock *GetCurrentBasicBlock();
|
||||
|
||||
|
||||
/** Set the given llvm::BasicBlock to be the basic block to emit
|
||||
forthcoming instructions into. */
|
||||
void SetCurrentBasicBlock(llvm::BasicBlock *bblock);
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
/** @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();
|
||||
|
||||
/** Returns the mask value corresponding to "varying" control flow
|
||||
@@ -106,7 +106,7 @@ public:
|
||||
llvm::Value *GetInternalMask();
|
||||
|
||||
/** 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();
|
||||
|
||||
/** 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
|
||||
break or continue), uniformControlFlow indicates whether the loop
|
||||
condition is 'uniform'. */
|
||||
void StartLoop(llvm::BasicBlock *breakTarget, llvm::BasicBlock *continueTarget,
|
||||
void StartLoop(llvm::BasicBlock *breakTarget, llvm::BasicBlock *continueTarget,
|
||||
bool uniformControlFlow);
|
||||
|
||||
/** 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
|
||||
after "case" statements to basic blocks corresponding
|
||||
to the "case" labels.
|
||||
@param nextBlocks For each basic block for a "case" or "default"
|
||||
label, this gives the basic block for the
|
||||
@param nextBlocks For each basic block for a "case" or "default"
|
||||
label, this gives the basic block for the
|
||||
immediately-following "case" or "default" label (or
|
||||
the basic block after the "switch" statement for the
|
||||
last label.)
|
||||
@@ -272,7 +272,7 @@ public:
|
||||
/** @} */
|
||||
|
||||
/** @name Small helper/utility routines
|
||||
@{
|
||||
@{
|
||||
*/
|
||||
/** Given a boolean mask value of type LLVMTypes::MaskType, return an
|
||||
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
|
||||
Instructions stored using Value pointers; the code here returns
|
||||
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);
|
||||
|
||||
/** Inform the debugging information generation code that a new scope
|
||||
@@ -361,7 +361,7 @@ public:
|
||||
instructions. See the LLVM assembly language reference manual
|
||||
(http://llvm.org/docs/LangRef.html) and the LLVM doxygen documentaion
|
||||
(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.
|
||||
|
||||
Beyond actually emitting the instruction, the implementations of
|
||||
@@ -377,7 +377,7 @@ public:
|
||||
this also handles applying the given operation to the vector
|
||||
elements. */
|
||||
llvm::Value *BinaryOperator(llvm::Instruction::BinaryOps inst,
|
||||
llvm::Value *v0, llvm::Value *v1,
|
||||
llvm::Value *v0, llvm::Value *v1,
|
||||
const char *name = NULL);
|
||||
|
||||
/** Emit the "not" operator. Like BinaryOperator(), this also handles
|
||||
@@ -387,7 +387,7 @@ public:
|
||||
/** Emit a comparison instruction. If the operands are VectorTypes,
|
||||
then a value for the corresponding boolean VectorType is
|
||||
returned. */
|
||||
llvm::Value *CmpInst(llvm::Instruction::OtherOps inst,
|
||||
llvm::Value *CmpInst(llvm::Instruction::OtherOps inst,
|
||||
llvm::CmpInst::Predicate pred,
|
||||
llvm::Value *v0, llvm::Value *v1, const char *name = NULL);
|
||||
|
||||
@@ -407,17 +407,17 @@ public:
|
||||
const char *name = NULL);
|
||||
llvm::Instruction *CastInst(llvm::Instruction::CastOps op, llvm::Value *value,
|
||||
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);
|
||||
llvm::Instruction *SExtInst(llvm::Value *value, llvm::Type *type,
|
||||
llvm::Instruction *SExtInst(llvm::Value *value, llvm::Type *type,
|
||||
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);
|
||||
|
||||
/** Given two integer-typed values (but possibly one vector and the
|
||||
other not, and or of possibly-different bit-widths), update their
|
||||
values as needed so that the two have the same (more general)
|
||||
type. */
|
||||
type. */
|
||||
void MatchIntegerTypes(llvm::Value **v0, llvm::Value **v1);
|
||||
|
||||
/** 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
|
||||
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
|
||||
the atEntryBlock parameter should be false. */
|
||||
llvm::Value *AllocaInst(llvm::Type *llvmType,
|
||||
const char *name = NULL, int align = 0,
|
||||
the atEntryBlock parameter should be false. */
|
||||
llvm::Value *AllocaInst(llvm::Type *llvmType,
|
||||
const char *name = NULL, int align = 0,
|
||||
bool atEntryBlock = true);
|
||||
|
||||
/** 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
|
||||
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,
|
||||
llvm::Value *align = NULL);
|
||||
|
||||
@@ -497,10 +497,10 @@ public:
|
||||
/** This convenience method maps to an llvm::InsertElementInst if the
|
||||
given value is a llvm::VectorType, and to an llvm::InsertValueInst
|
||||
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);
|
||||
|
||||
llvm::PHINode *PhiNode(llvm::Type *type, int count,
|
||||
llvm::PHINode *PhiNode(llvm::Type *type, int count,
|
||||
const char *name = NULL);
|
||||
llvm::Instruction *SelectInst(llvm::Value *test, llvm::Value *val0,
|
||||
llvm::Value *val1, const char *name = NULL);
|
||||
@@ -526,7 +526,7 @@ public:
|
||||
|
||||
/** Launch an asynchronous task to run the given function, passing it
|
||||
he given argument values. */
|
||||
llvm::Value *LaunchInst(llvm::Value *callee,
|
||||
llvm::Value *LaunchInst(llvm::Value *callee,
|
||||
std::vector<llvm::Value *> &argVals,
|
||||
llvm::Value *launchCount);
|
||||
|
||||
@@ -680,7 +680,7 @@ private:
|
||||
void jumpIfAllLoopLanesAreDone(llvm::BasicBlock *target);
|
||||
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);
|
||||
|
||||
void restoreMaskGivenReturns(llvm::Value *oldMask);
|
||||
@@ -694,7 +694,7 @@ private:
|
||||
const Type *ptrType, llvm::Value *mask);
|
||||
void maskedStore(llvm::Value *value, llvm::Value *ptr, const Type *ptrType,
|
||||
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,
|
||||
const PointerType *ptrType);
|
||||
llvm::Value *loadUniformFromSOA(llvm::Value *ptr, llvm::Value *mask,
|
||||
|
||||
36
decl.cpp
36
decl.cpp
@@ -28,11 +28,11 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@brief Implementations of classes related to turning declarations into
|
||||
@brief Implementations of classes related to turning declarations into
|
||||
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
|
||||
the type, returning the type that is the result.
|
||||
the type, returning the type that is the result.
|
||||
*/
|
||||
static const Type *
|
||||
lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
|
||||
@@ -97,7 +97,7 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
|
||||
if (unsignedType != NULL)
|
||||
type = unsignedType;
|
||||
else {
|
||||
const Type *resolvedType =
|
||||
const Type *resolvedType =
|
||||
type->ResolveUnboundVariability(Variability::Varying);
|
||||
Error(pos, "\"unsigned\" qualifier is illegal with \"%s\" type.",
|
||||
resolvedType->GetString().c_str());
|
||||
@@ -105,7 +105,7 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
|
||||
}
|
||||
|
||||
if ((typeQualifiers & TYPEQUAL_SIGNED) != 0 && type->IsIntType() == false) {
|
||||
const Type *resolvedType =
|
||||
const Type *resolvedType =
|
||||
type->ResolveUnboundVariability(Variability::Varying);
|
||||
Error(pos, "\"signed\" qualifier is illegal with non-integer type "
|
||||
"\"%s\".", resolvedType->GetString().c_str());
|
||||
@@ -147,7 +147,7 @@ DeclSpecs::GetBaseType(SourcePos pos) const {
|
||||
}
|
||||
|
||||
retType = lApplyTypeQualifiers(typeQualifiers, retType, pos);
|
||||
|
||||
|
||||
if (soaWidth > 0) {
|
||||
const StructType *st = CastType<StructType>(retType);
|
||||
|
||||
@@ -180,7 +180,7 @@ DeclSpecs::GetBaseType(SourcePos pos) const {
|
||||
"currently leads to inefficient code to access "
|
||||
"soa types.", soaWidth, g->target.vectorWidth);
|
||||
}
|
||||
|
||||
|
||||
return retType;
|
||||
}
|
||||
|
||||
@@ -215,8 +215,8 @@ DeclSpecs::Print() const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Declarator
|
||||
|
||||
Declarator::Declarator(DeclaratorKind dk, SourcePos p)
|
||||
: pos(p), kind(dk) {
|
||||
Declarator::Declarator(DeclaratorKind dk, SourcePos p)
|
||||
: pos(p), kind(dk) {
|
||||
child = NULL;
|
||||
typeQualifiers = 0;
|
||||
storageClass = SC_NONE;
|
||||
@@ -238,7 +238,7 @@ Declarator::InitFromDeclSpecs(DeclSpecs *ds) {
|
||||
|
||||
storageClass = ds->storageClass;
|
||||
|
||||
if (ds->declSpecList.size() > 0 &&
|
||||
if (ds->declSpecList.size() > 0 &&
|
||||
CastType<FunctionType>(type) == NULL) {
|
||||
Error(pos, "__declspec specifiers for non-function type \"%s\" are "
|
||||
"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.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Variability variability(Variability::Unbound);
|
||||
if (hasUniformQual)
|
||||
variability = Variability::Uniform;
|
||||
@@ -396,7 +396,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
||||
llvm::SmallVector<std::string, 8> argNames;
|
||||
llvm::SmallVector<Expr *, 8> argDefaults;
|
||||
llvm::SmallVector<SourcePos, 8> argPos;
|
||||
|
||||
|
||||
// Loop over the function arguments and store the names, types,
|
||||
// default values (if any), and source file positions each one in
|
||||
// the corresponding vector.
|
||||
@@ -431,7 +431,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
||||
|
||||
if (d->declSpecs->storageClass != SC_NONE)
|
||||
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),
|
||||
decl->name.c_str());
|
||||
if (Type::Equal(decl->type, AtomicType::Void)) {
|
||||
@@ -486,7 +486,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
||||
init = dynamic_cast<NullPointerExpr *>(decl->initExpr);
|
||||
if (init == NULL)
|
||||
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());
|
||||
}
|
||||
break;
|
||||
@@ -507,14 +507,14 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
||||
Error(pos, "Illegal to return function type from function.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
returnType = returnType->ResolveUnboundVariability(Variability::Varying);
|
||||
|
||||
bool isExternC = ds && (ds->storageClass == SC_EXTERN_C);
|
||||
bool isExported = ds && ((ds->typeQualifiers & TYPEQUAL_EXPORT) != 0);
|
||||
bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0);
|
||||
bool isUnmasked = ds && ((ds->typeQualifiers & TYPEQUAL_UNMASKED) != 0);
|
||||
|
||||
|
||||
if (isExported && isTask) {
|
||||
Error(pos, "Function can't have both \"task\" and \"export\" "
|
||||
"qualifiers");
|
||||
@@ -539,7 +539,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
||||
return;
|
||||
}
|
||||
|
||||
const FunctionType *functionType =
|
||||
const FunctionType *functionType =
|
||||
new FunctionType(returnType, args, argNames, argDefaults,
|
||||
argPos, isTask, isExported, isExternC, isUnmasked);
|
||||
|
||||
@@ -669,7 +669,7 @@ GetStructTypesNamesPositions(const std::vector<StructDeclaration *> &sd,
|
||||
// disgusting
|
||||
DeclSpecs ds(type);
|
||||
if (Type::Equal(type, AtomicType::Void) == false) {
|
||||
if (type->IsUniformType())
|
||||
if (type->IsUniformType())
|
||||
ds.typeQualifiers |= TYPEQUAL_UNIFORM;
|
||||
else if (type->IsVaryingType())
|
||||
ds.typeQualifiers |= TYPEQUAL_VARYING;
|
||||
|
||||
8
decl.h
8
decl.h
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -48,7 +48,7 @@
|
||||
qualifiers, and that it's basic type is 'int'. Then for each variable
|
||||
declaration, the Declaraiton class holds an instance of a Declarator,
|
||||
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
|
||||
@@ -124,7 +124,7 @@ enum DeclaratorKind {
|
||||
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
|
||||
everything we need for a full variable declaration.
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
StorageClass storageClass;
|
||||
|
||||
/** For array declarators, this gives the declared size of the array.
|
||||
Unsized arrays have arraySize == 0. */
|
||||
Unsized arrays have arraySize == 0. */
|
||||
int arraySize;
|
||||
|
||||
/** Name associated with the declarator. */
|
||||
|
||||
24
expr.h
24
expr.h
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -101,7 +101,7 @@ class UnaryExpr : public Expr {
|
||||
public:
|
||||
enum Op {
|
||||
PreInc, ///< Pre-increment
|
||||
PreDec, ///< Pre-decrement
|
||||
PreDec, ///< Pre-decrement
|
||||
PostInc, ///< Post-increment
|
||||
PostDec, ///< Post-decrement
|
||||
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".
|
||||
*/
|
||||
@@ -245,7 +245,7 @@ public:
|
||||
*/
|
||||
class FunctionCallExpr : public Expr {
|
||||
public:
|
||||
FunctionCallExpr(Expr *func, ExprList *args, SourcePos p,
|
||||
FunctionCallExpr(Expr *func, ExprList *args, SourcePos p,
|
||||
bool isLaunch = false, Expr *launchCountExpr = NULL);
|
||||
|
||||
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
||||
@@ -266,7 +266,7 @@ public:
|
||||
/** @brief Expression representing indexing into something with an integer
|
||||
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 {
|
||||
public:
|
||||
@@ -317,7 +317,7 @@ public:
|
||||
std::string identifier;
|
||||
const SourcePos identifierPos;
|
||||
|
||||
MemberExpr(Expr *expr, const char *identifier, SourcePos pos,
|
||||
MemberExpr(Expr *expr, const char *identifier, SourcePos pos,
|
||||
SourcePos identifierPos, bool derefLValue);
|
||||
|
||||
/** 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
|
||||
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
|
||||
used for a function call).
|
||||
*/
|
||||
*/
|
||||
class FunctionSymbolExpr : public Expr {
|
||||
public:
|
||||
FunctionSymbolExpr(const char *name, const std::vector<Symbol *> &candFuncs,
|
||||
@@ -714,7 +714,7 @@ public:
|
||||
class NullPointerExpr : public Expr {
|
||||
public:
|
||||
NullPointerExpr(SourcePos p) : Expr(p) { }
|
||||
|
||||
|
||||
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
||||
const Type *GetType() const;
|
||||
Expr *TypeCheck();
|
||||
@@ -726,11 +726,11 @@ public:
|
||||
|
||||
|
||||
/** An expression representing a "new" expression, used for dynamically
|
||||
allocating memory.
|
||||
allocating memory.
|
||||
*/
|
||||
class NewExpr : public Expr {
|
||||
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);
|
||||
|
||||
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
||||
@@ -742,7 +742,7 @@ public:
|
||||
|
||||
/** Type of object to allocate storage for. */
|
||||
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
|
||||
single element of the given type will be allocated. */
|
||||
Expr *countExpr;
|
||||
|
||||
32
func.cpp
32
func.cpp
@@ -28,11 +28,11 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@brief
|
||||
@brief
|
||||
*/
|
||||
|
||||
#include "func.h"
|
||||
@@ -85,7 +85,7 @@ Function::Function(Symbol *s, Stmt *c) {
|
||||
code = TypeCheck(code);
|
||||
|
||||
if (code != NULL && g->debugPrint) {
|
||||
fprintf(stderr, "After typechecking function \"%s\":\n",
|
||||
fprintf(stderr, "After typechecking function \"%s\":\n",
|
||||
sym->name.c_str());
|
||||
code->Print(0);
|
||||
fprintf(stderr, "---------------------\n");
|
||||
@@ -94,7 +94,7 @@ Function::Function(Symbol *s, Stmt *c) {
|
||||
if (code != NULL) {
|
||||
code = Optimize(code);
|
||||
if (g->debugPrint) {
|
||||
fprintf(stderr, "After optimizing function \"%s\":\n",
|
||||
fprintf(stderr, "After optimizing function \"%s\":\n",
|
||||
sym->name.c_str());
|
||||
code->Print(0);
|
||||
fprintf(stderr, "---------------------\n");
|
||||
@@ -160,7 +160,7 @@ Function::GetType() const {
|
||||
'mem2reg' pass will in turn promote to SSA registers..
|
||||
*/
|
||||
static void
|
||||
lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const
|
||||
lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const
|
||||
std::vector<Symbol *> &args,
|
||||
FunctionEmitContext *ctx) {
|
||||
// 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));
|
||||
const llvm::PointerType *pt = llvm::dyn_cast<const llvm::PointerType>(structArgType);
|
||||
Assert(llvm::isa<llvm::StructType>(pt->getElementType()));
|
||||
const llvm::StructType *argStructType =
|
||||
const llvm::StructType *argStructType =
|
||||
llvm::dyn_cast<const llvm::StructType>(pt->getElementType());
|
||||
|
||||
// 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
|
||||
function body code.
|
||||
*/
|
||||
void
|
||||
Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
||||
void
|
||||
Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
||||
SourcePos firstStmtPos) {
|
||||
// Connect the __mask builtin to the location in memory that stores its
|
||||
// value
|
||||
@@ -259,7 +259,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
||||
}
|
||||
else {
|
||||
// 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) {
|
||||
Symbol *sym = args[i];
|
||||
if (sym == NULL)
|
||||
@@ -301,14 +301,14 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
||||
ctx->AddInstrumentationPoint("function entry");
|
||||
|
||||
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);
|
||||
|
||||
// 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
|
||||
// on, all off, or mixed. If this is a simple function, then this
|
||||
// isn't worth the code bloat / overhead.
|
||||
bool checkMask = (type->isTask == true) ||
|
||||
bool checkMask = (type->isTask == true) ||
|
||||
(
|
||||
#if defined(LLVM_3_1)
|
||||
(function->hasFnAttr(llvm::Attribute::AlwaysInline) == false)
|
||||
@@ -322,7 +322,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
||||
checkMask &= (type->isUnmasked == false);
|
||||
checkMask &= (g->target.maskingIsFree == false);
|
||||
checkMask &= (g->opt.disableCoherentControlFlow == false);
|
||||
|
||||
|
||||
if (checkMask) {
|
||||
llvm::Value *mask = ctx->GetFunctionMask();
|
||||
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.
|
||||
if (function->empty() == false) {
|
||||
Error(sym->pos, "Ignoring redefinition of function \"%s\".",
|
||||
Error(sym->pos, "Ignoring redefinition of function \"%s\".",
|
||||
sym->name.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -426,7 +426,7 @@ Function::GenerateIR() {
|
||||
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);
|
||||
emitCode(&ec, function, firstStmtPos);
|
||||
@@ -451,7 +451,7 @@ Function::GenerateIR() {
|
||||
std::string functionName = sym->name;
|
||||
if (g->mangleFunctionsWithTarget)
|
||||
functionName += std::string("_") + g->target.GetISAString();
|
||||
llvm::Function *appFunction =
|
||||
llvm::Function *appFunction =
|
||||
llvm::Function::Create(ftype, linkage, functionName.c_str(), m->module);
|
||||
#if defined(LLVM_3_1)
|
||||
appFunction->setDoesNotThrow(true);
|
||||
@@ -470,7 +470,7 @@ Function::GenerateIR() {
|
||||
emitCode(&ec, appFunction, firstStmtPos);
|
||||
if (m->errorCount == 0) {
|
||||
sym->exportedFunction = appFunction;
|
||||
if (llvm::verifyFunction(*appFunction,
|
||||
if (llvm::verifyFunction(*appFunction,
|
||||
llvm::ReturnStatusAction) == true) {
|
||||
if (g->debugPrint)
|
||||
appFunction->dump();
|
||||
|
||||
4
func.h
4
func.h
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
void GenerateIR();
|
||||
|
||||
private:
|
||||
void emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
||||
void emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
||||
SourcePos firstStmtPos);
|
||||
|
||||
Symbol *sym;
|
||||
|
||||
42
ispc.cpp
42
ispc.cpp
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -136,7 +136,7 @@ lGetSystemISA() {
|
||||
}
|
||||
|
||||
|
||||
static const char *supportedCPUs[] = {
|
||||
static const char *supportedCPUs[] = {
|
||||
"atom", "penryn", "core2", "corei7", "corei7-avx"
|
||||
#if defined(LLVM_3_2) || defined(LLVM_3_3)
|
||||
, "core-avx-i", "core-avx2"
|
||||
@@ -187,7 +187,7 @@ Target::GetTarget(const char *arch, const char *cpu, const char *isa,
|
||||
}
|
||||
else {
|
||||
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) {
|
||||
if (!strcmp(cpu, supportedCPUs[i])) {
|
||||
foundCPU = true;
|
||||
@@ -405,7 +405,7 @@ Target::GetTarget(const char *arch, const char *cpu, const char *isa,
|
||||
#endif
|
||||
}
|
||||
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());
|
||||
error = true;
|
||||
}
|
||||
@@ -494,7 +494,7 @@ llvm::TargetMachine *
|
||||
Target::GetTargetMachine() const {
|
||||
std::string triple = GetTripleString();
|
||||
|
||||
llvm::Reloc::Model relocModel = generatePIC ? llvm::Reloc::PIC_ :
|
||||
llvm::Reloc::Model relocModel = generatePIC ? llvm::Reloc::PIC_ :
|
||||
llvm::Reloc::Default;
|
||||
std::string featuresString = attributes;
|
||||
llvm::TargetOptions options;
|
||||
@@ -502,7 +502,7 @@ Target::GetTargetMachine() const {
|
||||
if (g->opt.disableFMA == false)
|
||||
options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
|
||||
#endif // !LLVM_3_1
|
||||
llvm::TargetMachine *targetMachine =
|
||||
llvm::TargetMachine *targetMachine =
|
||||
target->createTargetMachine(triple, cpu, featuresString, options,
|
||||
relocModel);
|
||||
Assert(targetMachine != NULL);
|
||||
@@ -544,12 +544,12 @@ lGenericTypeLayoutIndeterminate(llvm::Type *type) {
|
||||
type == LLVMTypes::Int1VectorType)
|
||||
return true;
|
||||
|
||||
llvm::ArrayType *at =
|
||||
llvm::ArrayType *at =
|
||||
llvm::dyn_cast<llvm::ArrayType>(type);
|
||||
if (at != NULL)
|
||||
return lGenericTypeLayoutIndeterminate(at->getElementType());
|
||||
|
||||
llvm::PointerType *pt =
|
||||
llvm::PointerType *pt =
|
||||
llvm::dyn_cast<llvm::PointerType>(type);
|
||||
if (pt != NULL)
|
||||
return false;
|
||||
@@ -569,7 +569,7 @@ lGenericTypeLayoutIndeterminate(llvm::Type *type) {
|
||||
|
||||
|
||||
llvm::Value *
|
||||
Target::SizeOf(llvm::Type *type,
|
||||
Target::SizeOf(llvm::Type *type,
|
||||
llvm::BasicBlock *insertAtEnd) {
|
||||
if (isa == Target::GENERIC &&
|
||||
lGenericTypeLayoutIndeterminate(type)) {
|
||||
@@ -577,15 +577,15 @@ Target::SizeOf(llvm::Type *type,
|
||||
llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
|
||||
llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
|
||||
llvm::ArrayRef<llvm::Value *> arrayRef(&index[0], &index[1]);
|
||||
llvm::Instruction *gep =
|
||||
llvm::Instruction *gep =
|
||||
llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "sizeof_gep",
|
||||
insertAtEnd);
|
||||
|
||||
if (is32Bit || g->opt.force32BitAddressing)
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
|
||||
"sizeof_int", insertAtEnd);
|
||||
else
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
|
||||
"sizeof_int", insertAtEnd);
|
||||
}
|
||||
|
||||
@@ -611,25 +611,25 @@ Target::SizeOf(llvm::Type *type,
|
||||
llvm::Value *
|
||||
Target::StructOffset(llvm::Type *type, int element,
|
||||
llvm::BasicBlock *insertAtEnd) {
|
||||
if (isa == Target::GENERIC &&
|
||||
if (isa == Target::GENERIC &&
|
||||
lGenericTypeLayoutIndeterminate(type) == true) {
|
||||
llvm::Value *indices[2] = { LLVMInt32(0), LLVMInt32(element) };
|
||||
llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
|
||||
llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
|
||||
llvm::ArrayRef<llvm::Value *> arrayRef(&indices[0], &indices[2]);
|
||||
llvm::Instruction *gep =
|
||||
llvm::Instruction *gep =
|
||||
llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "offset_gep",
|
||||
insertAtEnd);
|
||||
|
||||
if (is32Bit || g->opt.force32BitAddressing)
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
|
||||
"offset_int", insertAtEnd);
|
||||
else
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
|
||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
|
||||
"offset_int", insertAtEnd);
|
||||
}
|
||||
|
||||
llvm::StructType *structType =
|
||||
llvm::StructType *structType =
|
||||
llvm::dyn_cast<llvm::StructType>(type);
|
||||
if (structType == NULL || structType->isSized() == false) {
|
||||
Assert(m->errorCount > 0);
|
||||
@@ -699,7 +699,7 @@ Globals::Globals() {
|
||||
enableFuzzTest = false;
|
||||
fuzzTestSeed = -1;
|
||||
mangleFunctionsWithTarget = false;
|
||||
|
||||
|
||||
ctx = new llvm::LLVMContext;
|
||||
|
||||
#ifdef ISPC_IS_WINDOWS
|
||||
@@ -739,15 +739,15 @@ SourcePos::GetDIFile() const {
|
||||
|
||||
|
||||
void
|
||||
SourcePos::Print() const {
|
||||
SourcePos::Print() const {
|
||||
printf(" @ [%s:%d.%d - %d.%d] ", name, first_line, first_column,
|
||||
last_line, last_column);
|
||||
last_line, last_column);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SourcePos::operator==(const SourcePos &p2) const {
|
||||
return (!strcmp(name, p2.name) &&
|
||||
return (!strcmp(name, p2.name) &&
|
||||
first_line == p2.first_line &&
|
||||
first_column == p2.first_column &&
|
||||
last_line == p2.last_line &&
|
||||
|
||||
18
ispc.h
18
ispc.h
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -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)))
|
||||
|
||||
|
||||
/** @brief Structure that defines a compilation target
|
||||
/** @brief Structure that defines a compilation target
|
||||
|
||||
This structure defines a compilation target for the ispc compiler.
|
||||
*/
|
||||
@@ -188,7 +188,7 @@ struct Target {
|
||||
/** Returns the LLVM TargetMachine object corresponding to this
|
||||
target. */
|
||||
llvm::TargetMachine *GetTargetMachine() const;
|
||||
|
||||
|
||||
/** Returns a string like "avx" encoding the target. */
|
||||
const char *GetISAString() const;
|
||||
|
||||
@@ -281,11 +281,11 @@ struct Target {
|
||||
/** @brief Structure that collects optimization options
|
||||
|
||||
This structure collects all of the options related to optimization of
|
||||
generated code.
|
||||
generated code.
|
||||
*/
|
||||
struct Opt {
|
||||
Opt();
|
||||
|
||||
|
||||
/** Optimization level. Currently, the only valid values are 0,
|
||||
indicating essentially no optimization, and 1, indicating as much
|
||||
optimization as possible. */
|
||||
@@ -308,7 +308,7 @@ struct Opt {
|
||||
/** Indicates if addressing math will be done with 32-bit math, even on
|
||||
64-bit systems. (This is generally noticably more efficient,
|
||||
though at the cost of addressing >2GB).
|
||||
*/
|
||||
*/
|
||||
bool force32BitAddressing;
|
||||
|
||||
/** Indicates whether Assert() statements should be ignored (for
|
||||
@@ -387,7 +387,7 @@ struct Opt {
|
||||
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
|
||||
represent parameter settings for this compilation run. In particular,
|
||||
@@ -445,12 +445,12 @@ struct Globals {
|
||||
externally-defined program instrumentation function. (See the
|
||||
"Instrumenting your ispc programs" section in the user's
|
||||
manual.) */
|
||||
bool emitInstrumentation;
|
||||
bool emitInstrumentation;
|
||||
|
||||
/** Indicates whether ispc should generate debugging symbols for the
|
||||
program in its output. */
|
||||
bool generateDebuggingSymbols;
|
||||
|
||||
|
||||
/** If true, function names are mangled by appending the target ISA and
|
||||
vector width to them. */
|
||||
bool mangleFunctionsWithTarget;
|
||||
|
||||
48
lex.ll
48
lex.ll
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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>
|
||||
#endif // ISPC_IS_WINDOWS
|
||||
|
||||
static int allTokens[] = {
|
||||
static int allTokens[] = {
|
||||
TOKEN_ASSERT, TOKEN_BOOL, TOKEN_BREAK, TOKEN_CASE,
|
||||
TOKEN_CDO, TOKEN_CFOR, TOKEN_CIF, TOKEN_CWHILE,
|
||||
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_SIZEOF, TOKEN_STATIC, TOKEN_STRUCT, TOKEN_SWITCH, TOKEN_SYNC,
|
||||
TOKEN_TASK, TOKEN_TRUE, TOKEN_TYPEDEF, TOKEN_UNIFORM, TOKEN_UNMASKED,
|
||||
TOKEN_UNSIGNED, TOKEN_VARYING, TOKEN_VOID, TOKEN_WHILE,
|
||||
TOKEN_STRING_C_LITERAL, TOKEN_DOTDOTDOT,
|
||||
TOKEN_UNSIGNED, TOKEN_VARYING, TOKEN_VOID, TOKEN_WHILE,
|
||||
TOKEN_STRING_C_LITERAL, TOKEN_DOTDOTDOT,
|
||||
TOKEN_FLOAT_CONSTANT,
|
||||
TOKEN_INT32_CONSTANT, TOKEN_UINT32_CONSTANT,
|
||||
TOKEN_INT64_CONSTANT, TOKEN_UINT64_CONSTANT,
|
||||
TOKEN_INT32_CONSTANT, TOKEN_UINT32_CONSTANT,
|
||||
TOKEN_INT64_CONSTANT, TOKEN_UINT64_CONSTANT,
|
||||
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_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; }
|
||||
|
||||
{IDENT} {
|
||||
{IDENT} {
|
||||
RT;
|
||||
/* We have an identifier--is it a type name or an identifier?
|
||||
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)
|
||||
return TOKEN_TYPE_NAME;
|
||||
else
|
||||
return TOKEN_IDENTIFIER;
|
||||
return TOKEN_IDENTIFIER;
|
||||
}
|
||||
|
||||
{INT_NUMBER} {
|
||||
{INT_NUMBER} {
|
||||
RT;
|
||||
return lParseInteger(false);
|
||||
}
|
||||
@@ -428,16 +428,16 @@ L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERA
|
||||
}
|
||||
|
||||
|
||||
{FLOAT_NUMBER} {
|
||||
{FLOAT_NUMBER} {
|
||||
RT;
|
||||
yylval.floatVal = (float)atof(yytext);
|
||||
return TOKEN_FLOAT_CONSTANT;
|
||||
return TOKEN_FLOAT_CONSTANT;
|
||||
}
|
||||
|
||||
{HEX_FLOAT_NUMBER} {
|
||||
RT;
|
||||
yylval.floatVal = (float)lParseHexFloat(yytext);
|
||||
return TOKEN_FLOAT_CONSTANT;
|
||||
yylval.floatVal = (float)lParseHexFloat(yytext);
|
||||
return TOKEN_FLOAT_CONSTANT;
|
||||
}
|
||||
|
||||
"++" { RT; return TOKEN_INC_OP; }
|
||||
@@ -489,17 +489,17 @@ L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERA
|
||||
{WHITESPACE} { }
|
||||
|
||||
\n {
|
||||
yylloc.last_line++;
|
||||
yylloc.last_column = 1;
|
||||
yylloc.last_line++;
|
||||
yylloc.last_column = 1;
|
||||
}
|
||||
|
||||
#(line)?[ ][0-9]+[ ]\"(\\.|[^\\"])*\"[^\n]* {
|
||||
lHandleCppHash(&yylloc);
|
||||
#(line)?[ ][0-9]+[ ]\"(\\.|[^\\"])*\"[^\n]* {
|
||||
lHandleCppHash(&yylloc);
|
||||
}
|
||||
|
||||
. {
|
||||
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')
|
||||
mega = true;
|
||||
else if (*endPtr == 'G')
|
||||
giga = true;
|
||||
giga = true;
|
||||
else if (*endPtr == 'l' || *endPtr == 'L')
|
||||
ls++;
|
||||
else if (*endPtr == 'u' || *endPtr == 'U')
|
||||
@@ -598,7 +598,7 @@ lParseInteger(bool dotdotdot) {
|
||||
return TOKEN_UINT64_CONSTANT;
|
||||
}
|
||||
else {
|
||||
// No u or l suffix
|
||||
// No u or l suffix
|
||||
// First, see if we can fit this into a 32-bit integer...
|
||||
if (yylval.intVal <= 0x7fffffffULL)
|
||||
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
|
||||
lCComment(SourcePos *pos) {
|
||||
@@ -750,7 +750,7 @@ lStringConst(YYSTYPE *yylval, SourcePos *pos)
|
||||
char cval = '\0';
|
||||
p = lEscapeChar(p, &cval, pos);
|
||||
str.push_back(cval);
|
||||
}
|
||||
}
|
||||
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.
|
||||
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
|
||||
obvious thing.
|
||||
obvious thing.
|
||||
*/
|
||||
static double
|
||||
ipow2(int exponent) {
|
||||
@@ -777,7 +777,7 @@ ipow2(int exponent) {
|
||||
|
||||
|
||||
/** Parse a hexadecimal-formatted floating-point number (C99 hex float
|
||||
constant-style).
|
||||
constant-style).
|
||||
*/
|
||||
static double
|
||||
lParseHexFloat(const char *ptr) {
|
||||
|
||||
82
llvmutil.cpp
82
llvmutil.cpp
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -124,19 +124,19 @@ InitLLVMUtil(llvm::LLVMContext *ctx, Target target) {
|
||||
llvm::VectorType::get(llvm::Type::getInt32Ty(*ctx), target.vectorWidth);
|
||||
}
|
||||
|
||||
LLVMTypes::Int1VectorType =
|
||||
LLVMTypes::Int1VectorType =
|
||||
llvm::VectorType::get(llvm::Type::getInt1Ty(*ctx), target.vectorWidth);
|
||||
LLVMTypes::Int8VectorType =
|
||||
LLVMTypes::Int8VectorType =
|
||||
llvm::VectorType::get(LLVMTypes::Int8Type, target.vectorWidth);
|
||||
LLVMTypes::Int16VectorType =
|
||||
LLVMTypes::Int16VectorType =
|
||||
llvm::VectorType::get(LLVMTypes::Int16Type, target.vectorWidth);
|
||||
LLVMTypes::Int32VectorType =
|
||||
LLVMTypes::Int32VectorType =
|
||||
llvm::VectorType::get(LLVMTypes::Int32Type, target.vectorWidth);
|
||||
LLVMTypes::Int64VectorType =
|
||||
LLVMTypes::Int64VectorType =
|
||||
llvm::VectorType::get(LLVMTypes::Int64Type, target.vectorWidth);
|
||||
LLVMTypes::FloatVectorType =
|
||||
LLVMTypes::FloatVectorType =
|
||||
llvm::VectorType::get(LLVMTypes::FloatType, target.vectorWidth);
|
||||
LLVMTypes::DoubleVectorType =
|
||||
LLVMTypes::DoubleVectorType =
|
||||
llvm::VectorType::get(LLVMTypes::DoubleType, target.vectorWidth);
|
||||
|
||||
LLVMTypes::Int8VectorPointerType = llvm::PointerType::get(LLVMTypes::Int8VectorType, 0);
|
||||
@@ -441,11 +441,11 @@ LLVMUInt64Vector(const uint64_t *ivec) {
|
||||
llvm::Constant *
|
||||
LLVMBoolVector(bool b) {
|
||||
llvm::Constant *v;
|
||||
if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
||||
v = llvm::ConstantInt::get(LLVMTypes::Int32Type, b ? 0xffffffff : 0,
|
||||
if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
||||
v = llvm::ConstantInt::get(LLVMTypes::Int32Type, b ? 0xffffffff : 0,
|
||||
false /*unsigned*/);
|
||||
else {
|
||||
Assert(LLVMTypes::BoolVectorType->getElementType() ==
|
||||
Assert(LLVMTypes::BoolVectorType->getElementType() ==
|
||||
llvm::Type::getInt1Ty(*g->ctx));
|
||||
v = b ? LLVMTrue : LLVMFalse;
|
||||
}
|
||||
@@ -462,11 +462,11 @@ LLVMBoolVector(const bool *bvec) {
|
||||
std::vector<llvm::Constant *> vals;
|
||||
for (int i = 0; i < g->target.vectorWidth; ++i) {
|
||||
llvm::Constant *v;
|
||||
if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
||||
v = llvm::ConstantInt::get(LLVMTypes::Int32Type, bvec[i] ? 0xffffffff : 0,
|
||||
if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
||||
v = llvm::ConstantInt::get(LLVMTypes::Int32Type, bvec[i] ? 0xffffffff : 0,
|
||||
false /*unsigned*/);
|
||||
else {
|
||||
Assert(LLVMTypes::BoolVectorType->getElementType() ==
|
||||
Assert(LLVMTypes::BoolVectorType->getElementType() ==
|
||||
llvm::Type::getInt1Ty(*g->ctx));
|
||||
v = bvec[i] ? LLVMTrue : LLVMFalse;
|
||||
}
|
||||
@@ -519,7 +519,7 @@ LLVMUIntAsType(uint64_t val, llvm::Type *type) {
|
||||
vectors definitely are equal.
|
||||
*/
|
||||
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 *> &seenPhi1) {
|
||||
// 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,
|
||||
// where we just return faliure in this case?
|
||||
Assert(phi0->getIncomingBlock(i) == phi1->getIncomingBlock(i));
|
||||
if (!lValuesAreEqual(phi0->getIncomingValue(i),
|
||||
if (!lValuesAreEqual(phi0->getIncomingValue(i),
|
||||
phi1->getIncomingValue(i), seenPhi0, seenPhi1)) {
|
||||
anyFailure = true;
|
||||
break;
|
||||
@@ -611,7 +611,7 @@ LLVMFlattenInsertChain(llvm::InsertElementInst *ie, int vectorWidth,
|
||||
Assert(iOffset >= 0 && iOffset < vectorWidth);
|
||||
Assert(elements[iOffset] == NULL);
|
||||
|
||||
// Get the scalar value from this insert
|
||||
// Get the scalar value from this insert
|
||||
elements[iOffset] = ie->getOperand(1);
|
||||
|
||||
// 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
|
||||
// have
|
||||
llvm::ConstantVector *cv =
|
||||
llvm::ConstantVector *cv =
|
||||
llvm::dyn_cast<llvm::ConstantVector>(insertBase);
|
||||
|
||||
// FIXME: this assert is a little questionable; we probably
|
||||
@@ -717,7 +717,7 @@ lIsExactMultiple(llvm::Value *val, int baseValue, int vectorLength,
|
||||
// we're good.
|
||||
for (unsigned int i = 0; i < numIncoming; ++i) {
|
||||
llvm::Value *incoming = phi->getIncomingValue(i);
|
||||
bool mult = lIsExactMultiple(incoming, baseValue, vectorLength,
|
||||
bool mult = lIsExactMultiple(incoming, baseValue, vectorLength,
|
||||
seenPhis);
|
||||
if (mult == false) {
|
||||
seenPhis.pop_back();
|
||||
@@ -748,9 +748,9 @@ lIsExactMultiple(llvm::Value *val, int baseValue, int vectorLength,
|
||||
static int
|
||||
lRoundUpPow2(int v) {
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
return v+1;
|
||||
@@ -804,7 +804,7 @@ lAllDivBaseEqual(llvm::Value *val, int64_t baseValue, int vectorLength,
|
||||
for (unsigned int i = 0; i < numIncoming; ++i) {
|
||||
llvm::Value *incoming = phi->getIncomingValue(i);
|
||||
bool ca = canAdd;
|
||||
bool mult = lAllDivBaseEqual(incoming, baseValue, vectorLength,
|
||||
bool mult = lAllDivBaseEqual(incoming, baseValue, vectorLength,
|
||||
seenPhis, ca);
|
||||
if (mult == false) {
|
||||
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);
|
||||
if (bop != NULL && bop->getOpcode() == llvm::Instruction::Add &&
|
||||
if (bop != NULL && bop->getOpcode() == llvm::Instruction::Add &&
|
||||
canAdd == true) {
|
||||
llvm::Value *op0 = bop->getOperand(0);
|
||||
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);
|
||||
if (bop != NULL) {
|
||||
// Easy case: both operands are all equal -> return true
|
||||
if (lVectorValuesAllEqual(bop->getOperand(0), vectorLength,
|
||||
if (lVectorValuesAllEqual(bop->getOperand(0), vectorLength,
|
||||
seenPhis) &&
|
||||
lVectorValuesAllEqual(bop->getOperand(1), vectorLength,
|
||||
lVectorValuesAllEqual(bop->getOperand(1), vectorLength,
|
||||
seenPhis))
|
||||
return true;
|
||||
|
||||
@@ -952,7 +952,7 @@ lVectorValuesAllEqual(llvm::Value *v, int vectorLength,
|
||||
// high (surviving) bits of the values are equal.
|
||||
if (bop->getOpcode() == llvm::Instruction::AShr ||
|
||||
bop->getOpcode() == llvm::Instruction::LShr)
|
||||
return lVectorShiftRightAllEqual(bop->getOperand(0),
|
||||
return lVectorShiftRightAllEqual(bop->getOperand(0),
|
||||
bop->getOperand(1), vectorLength);
|
||||
|
||||
return false;
|
||||
@@ -960,7 +960,7 @@ lVectorValuesAllEqual(llvm::Value *v, int vectorLength,
|
||||
|
||||
llvm::CastInst *cast = llvm::dyn_cast<llvm::CastInst>(v);
|
||||
if (cast != NULL)
|
||||
return lVectorValuesAllEqual(cast->getOperand(0), vectorLength,
|
||||
return lVectorValuesAllEqual(cast->getOperand(0), vectorLength,
|
||||
seenPhis);
|
||||
|
||||
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 *> seenPhi1;
|
||||
if (lValuesAreEqual(elements[lastNonNull], elements[i], seenPhi0,
|
||||
if (lValuesAreEqual(elements[lastNonNull], elements[i], seenPhi0,
|
||||
seenPhi1) == false)
|
||||
return false;
|
||||
lastNonNull = i;
|
||||
@@ -1087,8 +1087,8 @@ lVectorIsLinear(llvm::Value *v, int vectorLength, int stride,
|
||||
elements.
|
||||
*/
|
||||
static bool
|
||||
lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
|
||||
int vectorLength,
|
||||
lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
|
||||
int vectorLength,
|
||||
int stride) {
|
||||
// Flatten the vector out into the elements array
|
||||
llvm::SmallVector<llvm::Constant *, ISPC_MAX_NVEC> elements;
|
||||
@@ -1108,7 +1108,7 @@ lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
|
||||
// is stride. If not, fail.
|
||||
for (int i = 1; i < vectorLength; ++i) {
|
||||
ci = llvm::dyn_cast<llvm::ConstantInt>(elements[i]);
|
||||
if (ci == NULL)
|
||||
if (ci == NULL)
|
||||
return false;
|
||||
|
||||
int64_t nextVal = ci->getSExtValue();
|
||||
@@ -1125,7 +1125,7 @@ lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
|
||||
vector with values that increase by stride.
|
||||
*/
|
||||
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) {
|
||||
// Is the first operand a constant integer value splatted across all of
|
||||
// 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
|
||||
// given by stride/splatVal.
|
||||
return lVectorIsLinear(op1, vectorLength, (int)(stride / splatVal),
|
||||
return lVectorIsLinear(op1, vectorLength, (int)(stride / splatVal),
|
||||
seenPhis);
|
||||
}
|
||||
|
||||
@@ -1161,7 +1161,7 @@ lCheckMulForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
|
||||
data.
|
||||
*/
|
||||
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) {
|
||||
// Require op1 to be a compile-time constant
|
||||
int64_t maskValue[ISPC_MAX_NVEC];
|
||||
@@ -1359,7 +1359,7 @@ LLVMDumpValue(llvm::Value *v) {
|
||||
|
||||
|
||||
static llvm::Value *
|
||||
lExtractFirstVectorElement(llvm::Value *v,
|
||||
lExtractFirstVectorElement(llvm::Value *v,
|
||||
std::map<llvm::PHINode *, llvm::PHINode *> &phiMap) {
|
||||
llvm::VectorType *vt =
|
||||
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)) {
|
||||
return cv->getOperand(0);
|
||||
}
|
||||
if (llvm::ConstantDataVector *cdv =
|
||||
if (llvm::ConstantDataVector *cdv =
|
||||
llvm::dyn_cast<llvm::ConstantDataVector>(v))
|
||||
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
|
||||
// start of the bblock of the original phi node.
|
||||
llvm::Instruction *phiInsertPos = phi->getParent()->begin();
|
||||
llvm::PHINode *scalarPhi =
|
||||
llvm::PHINode::Create(vt->getElementType(),
|
||||
phi->getNumIncomingValues(),
|
||||
llvm::PHINode *scalarPhi =
|
||||
llvm::PHINode::Create(vt->getElementType(),
|
||||
phi->getNumIncomingValues(),
|
||||
newName, phiInsertPos);
|
||||
phiMap[phi] = scalarPhi;
|
||||
|
||||
@@ -1452,7 +1452,7 @@ lExtractFirstVectorElement(llvm::Value *v,
|
||||
// have here.
|
||||
llvm::Instruction *insertAfter = llvm::dyn_cast<llvm::Instruction>(v);
|
||||
Assert(insertAfter != NULL);
|
||||
llvm::Instruction *ee =
|
||||
llvm::Instruction *ee =
|
||||
llvm::ExtractElementInst::Create(v, LLVMInt32(0), "first_elt",
|
||||
(llvm::Instruction *)NULL);
|
||||
ee->insertAfter(insertAfter);
|
||||
@@ -1474,7 +1474,7 @@ LLVMExtractFirstVectorElement(llvm::Value *v) {
|
||||
vector.
|
||||
*/
|
||||
llvm::Value *
|
||||
LLVMConcatVectors(llvm::Value *v1, llvm::Value *v2,
|
||||
LLVMConcatVectors(llvm::Value *v1, llvm::Value *v2,
|
||||
llvm::Instruction *insertBefore) {
|
||||
Assert(v1->getType() == v2->getType());
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -59,7 +59,7 @@ namespace llvm {
|
||||
/** This structure holds pointers to a variety of LLVM types; code
|
||||
elsewhere can use them from here, ratherthan needing to make more
|
||||
verbose LLVM API calls.
|
||||
*/
|
||||
*/
|
||||
struct LLVMTypes {
|
||||
static llvm::Type *VoidType;
|
||||
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
|
||||
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
|
||||
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
|
||||
returns a new vector of twice the length that represents concatenating
|
||||
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);
|
||||
|
||||
/** This is a utility function for vector shuffling; it takes two vectors
|
||||
|
||||
26
main.cpp
26
main.cpp
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -60,8 +60,8 @@
|
||||
|
||||
static void
|
||||
lPrintVersion() {
|
||||
printf("Intel(r) SPMD Program Compiler (ispc), %s (build %s @ %s, LLVM %s)\n",
|
||||
ISPC_VERSION, BUILD_VERSION, BUILD_DATE,
|
||||
printf("Intel(r) SPMD Program Compiler (ispc), %s (build %s @ %s, LLVM %s)\n",
|
||||
ISPC_VERSION, BUILD_VERSION, BUILD_DATE,
|
||||
#if defined(LLVM_3_1)
|
||||
"3.1"
|
||||
#elif defined(LLVM_3_2)
|
||||
@@ -70,7 +70,7 @@ lPrintVersion() {
|
||||
"3.3"
|
||||
#else
|
||||
#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(" \t\taddressing calculations are done by default, even\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());
|
||||
printf(" [--c++-include-file=<name>]\t\tSpecify name of file to emit in #include statement in generated C++ code.\n");
|
||||
#ifndef ISPC_IS_WINDOWS
|
||||
@@ -160,7 +160,7 @@ devUsage(int ret) {
|
||||
/** We take arguments from both the command line as well as from the
|
||||
ISPC_ARGS environment variable. This function returns a new set of
|
||||
arguments representing the ones from those two sources merged together.
|
||||
*/
|
||||
*/
|
||||
static void lGetAllArgs(int Argc, char *Argv[], int &argc, char *argv[128]) {
|
||||
// Copy over the command line arguments (passed in)
|
||||
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);
|
||||
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;
|
||||
if (*end == '\0')
|
||||
break;
|
||||
@@ -403,7 +403,7 @@ int main(int Argc, char *Argv[]) {
|
||||
g->opt.level = 0;
|
||||
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")) {
|
||||
g->opt.level = 1;
|
||||
optSet = true;
|
||||
@@ -480,7 +480,7 @@ int main(int Argc, char *Argv[]) {
|
||||
int seed = getpid();
|
||||
#endif
|
||||
g->fuzzTestSeed = seed;
|
||||
Warning(SourcePos(), "Using seed %d for fuzz testing",
|
||||
Warning(SourcePos(), "Using seed %d for fuzz testing",
|
||||
g->fuzzTestSeed);
|
||||
}
|
||||
#ifdef ISPC_IS_WINDOWS
|
||||
@@ -490,7 +490,7 @@ int main(int Argc, char *Argv[]) {
|
||||
#endif
|
||||
}
|
||||
|
||||
if (outFileName == NULL &&
|
||||
if (outFileName == NULL &&
|
||||
headerFileName == NULL &&
|
||||
depsFileName == NULL &&
|
||||
hostStubFileName == NULL &&
|
||||
@@ -500,9 +500,9 @@ int main(int Argc, char *Argv[]) {
|
||||
"be issued, but no output will be generated.");
|
||||
|
||||
return Module::CompileAndOutput(file, arch, cpu, target, generatePIC,
|
||||
ot,
|
||||
outFileName,
|
||||
headerFileName,
|
||||
ot,
|
||||
outFileName,
|
||||
headerFileName,
|
||||
includeFileName,
|
||||
depsFileName,
|
||||
hostStubFileName,
|
||||
|
||||
218
module.cpp
218
module.cpp
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -163,7 +163,7 @@ lStripUnusedDebugInfo(llvm::Module *module) {
|
||||
|
||||
// And now loop over the subprograms inside each compile unit.
|
||||
for (unsigned j = 0, je = subprograms.getNumElements(); j != je; ++j) {
|
||||
llvm::MDNode *spNode =
|
||||
llvm::MDNode *spNode =
|
||||
llvm::dyn_cast<llvm::MDNode>(subprograms->getOperand(j));
|
||||
Assert(spNode != NULL);
|
||||
llvm::DISubprogram sp(spNode);
|
||||
@@ -197,7 +197,7 @@ lStripUnusedDebugInfo(llvm::Module *module) {
|
||||
// debugging metadata organization on the LLVM side changed,
|
||||
// here is a bunch of asserting to make sure that element 12 of
|
||||
// the compile unit's MDNode has the subprograms array....
|
||||
llvm::MDNode *nodeSPMD =
|
||||
llvm::MDNode *nodeSPMD =
|
||||
llvm::dyn_cast<llvm::MDNode>(cuNode->getOperand(12));
|
||||
Assert(nodeSPMD != NULL);
|
||||
llvm::MDNode *nodeSPMDArray =
|
||||
@@ -209,9 +209,9 @@ lStripUnusedDebugInfo(llvm::Module *module) {
|
||||
|
||||
// And now we can go and stuff it into the node with some
|
||||
// confidence...
|
||||
llvm::Value *usedSubprogramsArray =
|
||||
llvm::Value *usedSubprogramsArray =
|
||||
m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(usedSubprograms));
|
||||
llvm::MDNode *replNode =
|
||||
llvm::MDNode *replNode =
|
||||
llvm::MDNode::get(*g->ctx, llvm::ArrayRef<llvm::Value *>(usedSubprogramsArray));
|
||||
cuNode->replaceOperandWith(12, replNode);
|
||||
}
|
||||
@@ -349,7 +349,7 @@ Module::CompileFile() {
|
||||
else {
|
||||
// No preprocessor, just open up the file if it's not stdin..
|
||||
FILE* f = NULL;
|
||||
if (filename == NULL)
|
||||
if (filename == NULL)
|
||||
f = stdin;
|
||||
else {
|
||||
f = fopen(filename, "r");
|
||||
@@ -383,7 +383,7 @@ Module::AddTypeDef(const std::string &name, const Type *type,
|
||||
|
||||
|
||||
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) {
|
||||
// These may be NULL due to errors in parsing; just gracefully return
|
||||
// here if so.
|
||||
@@ -420,7 +420,7 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
|
||||
"expression.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
llvm::Type *llvmType = type->LLVMType(g->ctx);
|
||||
if (llvmType == NULL)
|
||||
return;
|
||||
@@ -444,7 +444,7 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
|
||||
// convert themselves anyway.)
|
||||
if (dynamic_cast<ExprList *>(initExpr) == NULL)
|
||||
initExpr = TypeConvertExpr(initExpr, type, "initializer");
|
||||
|
||||
|
||||
if (initExpr != NULL) {
|
||||
initExpr = Optimize(initExpr);
|
||||
// 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 (!Type::Equal(sym->type, type) ||
|
||||
(sym->storageClass != SC_EXTERN &&
|
||||
(sym->storageClass != SC_EXTERN &&
|
||||
sym->storageClass != SC_EXTERN_C &&
|
||||
sym->storageClass != storageClass)) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
llvm::GlobalVariable *gv =
|
||||
llvm::GlobalVariable *gv =
|
||||
llvm::dyn_cast<llvm::GlobalVariable>(sym->storagePtr);
|
||||
Assert(gv != NULL);
|
||||
|
||||
// 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) {
|
||||
Error(pos, "Redefinition of variable \"%s\" is illegal. "
|
||||
"(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"
|
||||
// declarations coming up extern and not defining storage (a bit
|
||||
// subtle)...
|
||||
sym->storagePtr = new llvm::GlobalVariable(*module, llvmType, isConst,
|
||||
linkage, llvmInitializer,
|
||||
sym->storagePtr = new llvm::GlobalVariable(*module, llvmType, isConst,
|
||||
linkage, llvmInitializer,
|
||||
sym->name.c_str());
|
||||
|
||||
// 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();
|
||||
sym->storagePtr->setName(sym->name.c_str());
|
||||
}
|
||||
|
||||
|
||||
if (diBuilder) {
|
||||
llvm::DIFile file = pos.GetDIFile();
|
||||
llvm::DIGlobalVariable var =
|
||||
diBuilder->createGlobalVariable(name,
|
||||
diBuilder->createGlobalVariable(name,
|
||||
file,
|
||||
pos.first_line,
|
||||
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
|
||||
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
|
||||
types are found and returns false otherwise.
|
||||
types are found and returns false otherwise.
|
||||
*/
|
||||
static bool
|
||||
lRecursiveCheckValidParamType(const Type *t, bool vectorOk) {
|
||||
@@ -601,7 +601,7 @@ lRecursiveCheckValidParamType(const Type *t, bool vectorOk) {
|
||||
varying parameters is illegal.
|
||||
*/
|
||||
static void
|
||||
lCheckExportedParameterTypes(const Type *type, const std::string &name,
|
||||
lCheckExportedParameterTypes(const Type *type, const std::string &name,
|
||||
SourcePos pos) {
|
||||
if (lRecursiveCheckValidParamType(type, false) == false) {
|
||||
if (CastType<PointerType>(type))
|
||||
@@ -645,8 +645,8 @@ lCheckForStructParameters(const FunctionType *ftype, SourcePos pos) {
|
||||
false if any errors were encountered.
|
||||
*/
|
||||
void
|
||||
Module::AddFunctionDeclaration(const std::string &name,
|
||||
const FunctionType *functionType,
|
||||
Module::AddFunctionDeclaration(const std::string &name,
|
||||
const FunctionType *functionType,
|
||||
StorageClass storageClass, bool isInline,
|
||||
SourcePos pos) {
|
||||
Assert(functionType != NULL);
|
||||
@@ -666,7 +666,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
||||
for (unsigned int i = 0; i < overloadFuncs.size(); ++i) {
|
||||
Symbol *overloadFunc = overloadFuncs[i];
|
||||
|
||||
const FunctionType *overloadType =
|
||||
const FunctionType *overloadType =
|
||||
CastType<FunctionType>(overloadFunc->type);
|
||||
if (overloadType == NULL) {
|
||||
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
|
||||
// different, return an error--overloading by return type isn't
|
||||
// allowed.
|
||||
const FunctionType *ofType =
|
||||
const FunctionType *ofType =
|
||||
CastType<FunctionType>(overloadFunc->type);
|
||||
Assert(ofType != NULL);
|
||||
if (ofType->GetNumParameters() == functionType->GetNumParameters()) {
|
||||
@@ -725,7 +725,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
||||
symbolTable->LookupFunction(name.c_str(), &funcs);
|
||||
if (funcs.size() > 0) {
|
||||
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
|
||||
Error(pos, "Can't overload extern \"C\" function \"%s\"; "
|
||||
"%d functions with the same name have already been declared.",
|
||||
@@ -747,7 +747,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
||||
|
||||
// Get the LLVM FunctionType
|
||||
bool disableMask = (storageClass == SC_EXTERN_C);
|
||||
llvm::FunctionType *llvmFunctionType =
|
||||
llvm::FunctionType *llvmFunctionType =
|
||||
functionType->LLVMFunctionType(g->ctx, disableMask);
|
||||
if (llvmFunctionType == NULL)
|
||||
return;
|
||||
@@ -763,13 +763,13 @@ Module::AddFunctionDeclaration(const std::string &name,
|
||||
if (g->mangleFunctionsWithTarget)
|
||||
functionName += g->target.GetISAString();
|
||||
}
|
||||
llvm::Function *function =
|
||||
llvm::Function::Create(llvmFunctionType, linkage, functionName.c_str(),
|
||||
llvm::Function *function =
|
||||
llvm::Function::Create(llvmFunctionType, linkage, functionName.c_str(),
|
||||
module);
|
||||
|
||||
// Set function attributes: we never throw exceptions
|
||||
function->setDoesNotThrow();
|
||||
if (storageClass != SC_EXTERN_C &&
|
||||
if (storageClass != SC_EXTERN_C &&
|
||||
!g->generateDebuggingSymbols &&
|
||||
isInline)
|
||||
#ifdef LLVM_3_2
|
||||
@@ -778,7 +778,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
||||
function->addFnAttr(llvm::Attribute::AlwaysInline);
|
||||
#endif
|
||||
if (functionType->isTask)
|
||||
// This also applies transitively to members I think?
|
||||
// This also applies transitively to members I think?
|
||||
#if defined(LLVM_3_1)
|
||||
function->setDoesNotAlias(1, true);
|
||||
#else
|
||||
@@ -791,12 +791,12 @@ Module::AddFunctionDeclaration(const std::string &name,
|
||||
|
||||
// Make sure that the return type isn't 'varying' or vector typed if
|
||||
// the function is 'export'ed.
|
||||
if (functionType->isExported &&
|
||||
if (functionType->isExported &&
|
||||
lRecursiveCheckValidParamType(functionType->GetReturnType(), false) == false)
|
||||
Error(pos, "Illegal to return a \"varying\" or vector type from "
|
||||
"exported function \"%s\"", name.c_str());
|
||||
|
||||
if (functionType->isTask &&
|
||||
if (functionType->isTask &&
|
||||
Type::Equal(functionType->GetReturnType(), AtomicType::Void) == false)
|
||||
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
|
||||
// default.) Set parameter attributes accordingly. (Only for
|
||||
// uniform pointers, since varying pointers are int vectors...)
|
||||
if (!functionType->isTask &&
|
||||
if (!functionType->isTask &&
|
||||
((CastType<PointerType>(argType) != NULL &&
|
||||
argType->IsUniformType() &&
|
||||
// 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()))
|
||||
Warning(argPos, "Function parameter \"%s\" shadows a function "
|
||||
"declared in global scope.", argName.c_str());
|
||||
|
||||
|
||||
if (defaultValue != NULL)
|
||||
seenDefaultArg = true;
|
||||
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
|
||||
// earlier been declared with anonymous parameter names but is now
|
||||
// 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;
|
||||
|
||||
ast->AddFunction(sym, code);
|
||||
@@ -902,14 +902,14 @@ Module::AddFunctionDefinition(const std::string &name, const FunctionType *type,
|
||||
|
||||
|
||||
void
|
||||
Module::AddExportedTypes(const std::vector<std::pair<const Type *,
|
||||
Module::AddExportedTypes(const std::vector<std::pair<const Type *,
|
||||
SourcePos> > &types) {
|
||||
for (int i = 0; i < (int)types.size(); ++i) {
|
||||
if (CastType<StructType>(types[i].first) == NULL &&
|
||||
CastType<VectorType>(types[i].first) == NULL &&
|
||||
CastType<EnumType>(types[i].first) == NULL)
|
||||
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());
|
||||
else
|
||||
exportedTypes.push_back(types[i]);
|
||||
@@ -996,7 +996,7 @@ Module::writeOutput(OutputType outputType, const char *outFileName,
|
||||
"C++ emission.");
|
||||
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);
|
||||
return WriteCXXFile(module, outFileName, g->target.vectorWidth,
|
||||
includeFileName);
|
||||
@@ -1044,11 +1044,11 @@ Module::writeObjectFileOrAssembly(OutputType outputType, const char *outFileName
|
||||
|
||||
bool
|
||||
Module::writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
|
||||
llvm::Module *module, OutputType outputType,
|
||||
llvm::Module *module, OutputType outputType,
|
||||
const char *outFileName) {
|
||||
// Figure out if we're generating object file or assembly output, and
|
||||
// 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;
|
||||
bool binary = (fileType == llvm::TargetMachine::CGFT_ObjectFile);
|
||||
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
|
||||
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();
|
||||
|
||||
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.
|
||||
for (int i = 0; i < st->GetElementCount(); ++i) {
|
||||
const StructType *elementStructType =
|
||||
const StructType *elementStructType =
|
||||
lGetElementStructType(st->GetElementType(i));
|
||||
if (elementStructType != NULL)
|
||||
lEmitStructDecl(elementStructType, emittedStructs, file);
|
||||
@@ -1172,14 +1172,14 @@ lEmitEnumDecls(const std::vector<const EnumType *> &enumTypes, FILE *file) {
|
||||
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
|
||||
fprintf(file, "// Enumerator types with external visibility from ispc code\n");
|
||||
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n\n");
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < enumTypes.size(); ++i) {
|
||||
fprintf(file, "#ifndef __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("");
|
||||
fprintf(file, "%s {\n", declaration.c_str());
|
||||
|
||||
// Print the individual enumerators
|
||||
// Print the individual enumerators
|
||||
for (int j = 0; j < enumTypes[i]->GetEnumeratorCount(); ++j) {
|
||||
const Symbol *e = enumTypes[i]->GetEnumerator(j);
|
||||
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,
|
||||
baseDecl.c_str(), size);
|
||||
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);
|
||||
fprintf(file, "#endif\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.
|
||||
*/
|
||||
static void
|
||||
lGetExportedTypes(const Type *type,
|
||||
lGetExportedTypes(const Type *type,
|
||||
std::vector<const StructType *> *exportedStructTypes,
|
||||
std::vector<const EnumType *> *exportedEnumTypes,
|
||||
std::vector<const VectorType *> *exportedVectorTypes) {
|
||||
@@ -1273,13 +1273,13 @@ lGetExportedTypes(const Type *type,
|
||||
const StructType *structType = CastType<StructType>(type);
|
||||
|
||||
if (CastType<ReferenceType>(type) != NULL)
|
||||
lGetExportedTypes(type->GetReferenceTarget(), exportedStructTypes,
|
||||
lGetExportedTypes(type->GetReferenceTarget(), exportedStructTypes,
|
||||
exportedEnumTypes, exportedVectorTypes);
|
||||
else if (CastType<PointerType>(type) != NULL)
|
||||
lGetExportedTypes(type->GetBaseType(), exportedStructTypes,
|
||||
exportedEnumTypes, exportedVectorTypes);
|
||||
else if (arrayType != NULL)
|
||||
lGetExportedTypes(arrayType->GetElementType(), exportedStructTypes,
|
||||
lGetExportedTypes(arrayType->GetElementType(), exportedStructTypes,
|
||||
exportedEnumTypes, exportedVectorTypes);
|
||||
else if (structType != NULL) {
|
||||
lAddTypeIfNew(type, exportedStructTypes);
|
||||
@@ -1303,7 +1303,7 @@ lGetExportedTypes(const Type *type,
|
||||
present in the parameters to them.
|
||||
*/
|
||||
static void
|
||||
lGetExportedParamTypes(const std::vector<Symbol *> &funcs,
|
||||
lGetExportedParamTypes(const std::vector<Symbol *> &funcs,
|
||||
std::vector<const StructType *> *exportedStructTypes,
|
||||
std::vector<const EnumType *> *exportedEnumTypes,
|
||||
std::vector<const VectorType *> *exportedVectorTypes) {
|
||||
@@ -1383,7 +1383,7 @@ std::string emitOffloadParamStruct(const std::string ¶mStructName,
|
||||
{
|
||||
std::stringstream out;
|
||||
out << "struct " << paramStructName << " {" << std::endl;
|
||||
|
||||
|
||||
for (int i=0;i<fct->GetNumParameters();i++) {
|
||||
const Type *orgParamType = fct->GetParameterType(i);
|
||||
if (orgParamType->IsPointerType() || orgParamType->IsArrayType()) {
|
||||
@@ -1405,7 +1405,7 @@ std::string emitOffloadParamStruct(const std::string ¶mStructName,
|
||||
}
|
||||
std::string paramName = fct->GetParameterName(i);
|
||||
std::string paramTypeName = paramType->GetString();
|
||||
|
||||
|
||||
std::string tmpArgDecl = paramType->GetCDeclaration(paramName);
|
||||
out << " " << tmpArgDecl << ";" << std::endl;
|
||||
}
|
||||
@@ -1415,7 +1415,7 @@ std::string emitOffloadParamStruct(const std::string ¶mStructName,
|
||||
}
|
||||
|
||||
bool
|
||||
Module::writeDevStub(const char *fn)
|
||||
Module::writeDevStub(const char *fn)
|
||||
{
|
||||
FILE *file = fopen(fn, "w");
|
||||
if (!file) {
|
||||
@@ -1427,14 +1427,14 @@ Module::writeDevStub(const char *fn)
|
||||
fprintf(file,"#include \"ispc/dev/offload.h\"\n\n");
|
||||
|
||||
fprintf(file, "#include <stdint.h>\n\n");
|
||||
|
||||
|
||||
// Collect single linear arrays of the *exported* functions (we'll
|
||||
// treat those as "__kernel"s in IVL -- "extern" functions will only
|
||||
// be used for dev-dev function calls; only "export" functions will
|
||||
// get exported to the host
|
||||
std::vector<Symbol *> exportedFuncs;
|
||||
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
|
||||
|
||||
|
||||
// Get all of the struct, vector, and enumerant types used as function
|
||||
// parameters. These vectors may have repeats.
|
||||
std::vector<const StructType *> exportedStructTypes;
|
||||
@@ -1442,12 +1442,12 @@ Module::writeDevStub(const char *fn)
|
||||
std::vector<const VectorType *> exportedVectorTypes;
|
||||
lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
|
||||
&exportedEnumTypes, &exportedVectorTypes);
|
||||
|
||||
|
||||
// And print them
|
||||
lEmitVectorTypedefs(exportedVectorTypes, file);
|
||||
lEmitEnumDecls(exportedEnumTypes, file);
|
||||
lEmitStructDecls(exportedStructTypes, file);
|
||||
|
||||
|
||||
fprintf(file, "#ifdef __cplusplus\n");
|
||||
fprintf(file, "namespace ispc {\n");
|
||||
fprintf(file, "#endif // __cplusplus\n");
|
||||
@@ -1475,7 +1475,7 @@ Module::writeDevStub(const char *fn)
|
||||
Assert(sym);
|
||||
const FunctionType *fct = CastType<FunctionType>(sym->type);
|
||||
Assert(fct);
|
||||
|
||||
|
||||
if (!fct->GetReturnType()->IsVoidType()) {
|
||||
//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");
|
||||
@@ -1505,7 +1505,7 @@ Module::writeDevStub(const char *fn)
|
||||
fprintf(file," struct %s args;\n memcpy(&args,in_pMiscData,sizeof(args));\n",
|
||||
paramStructName.c_str());
|
||||
std::stringstream funcall;
|
||||
|
||||
|
||||
funcall << "ispc::" << sym->name << "(";
|
||||
for (int i=0;i<fct->GetNumParameters();i++) {
|
||||
// get param type and make it non-const, so we can write while unpacking
|
||||
@@ -1522,7 +1522,7 @@ Module::writeDevStub(const char *fn)
|
||||
} else {
|
||||
paramType = orgParamType->GetAsNonConstType();
|
||||
}
|
||||
|
||||
|
||||
std::string paramName = fct->GetParameterName(i);
|
||||
std::string paramTypeName = paramType->GetString();
|
||||
|
||||
@@ -1554,7 +1554,7 @@ Module::writeDevStub(const char *fn)
|
||||
|
||||
|
||||
bool
|
||||
Module::writeHostStub(const char *fn)
|
||||
Module::writeHostStub(const char *fn)
|
||||
{
|
||||
FILE *file = fopen(fn, "w");
|
||||
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\nnamespace ispc {\n#endif // __cplusplus\n\n");
|
||||
|
||||
|
||||
// Collect single linear arrays of the *exported* functions (we'll
|
||||
// treat those as "__kernel"s in IVL -- "extern" functions will only
|
||||
// be used for dev-dev function calls; only "export" functions will
|
||||
// get exported to the host
|
||||
std::vector<Symbol *> exportedFuncs;
|
||||
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
|
||||
|
||||
|
||||
// Get all of the struct, vector, and enumerant types used as function
|
||||
// parameters. These vectors may have repeats.
|
||||
std::vector<const StructType *> exportedStructTypes;
|
||||
@@ -1583,12 +1583,12 @@ Module::writeHostStub(const char *fn)
|
||||
std::vector<const VectorType *> exportedVectorTypes;
|
||||
lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
|
||||
&exportedEnumTypes, &exportedVectorTypes);
|
||||
|
||||
|
||||
// And print them
|
||||
lEmitVectorTypedefs(exportedVectorTypes, file);
|
||||
lEmitEnumDecls(exportedEnumTypes, file);
|
||||
lEmitStructDecls(exportedStructTypes, file);
|
||||
|
||||
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "///////////////////////////////////////////////////////////////////////////\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
|
||||
// -------------------------------------------------------
|
||||
|
||||
|
||||
std::string decl = fct->GetCDeclaration(sym->name);
|
||||
fprintf(file, "extern %s {\n", decl.c_str());
|
||||
int numPointers = 0;
|
||||
@@ -1661,7 +1661,7 @@ Module::writeHostStub(const char *fn)
|
||||
numPointers);
|
||||
fprintf(file,"}\n\n");
|
||||
}
|
||||
|
||||
|
||||
// end extern "C"
|
||||
fprintf(file, "#ifdef __cplusplus\n");
|
||||
fprintf(file, "}/* namespace */\n");
|
||||
@@ -1669,7 +1669,7 @@ Module::writeHostStub(const char *fn)
|
||||
// fprintf(file, "#ifdef __cplusplus\n");
|
||||
// fprintf(file, "}/* end extern C */\n");
|
||||
// fprintf(file, "#endif // __cplusplus\n");
|
||||
|
||||
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
@@ -1690,9 +1690,9 @@ Module::writeHeader(const char *fn) {
|
||||
std::string guard = "ISPC_";
|
||||
const char *p = fn;
|
||||
while (*p) {
|
||||
if (isdigit(*p))
|
||||
if (isdigit(*p))
|
||||
guard += *p;
|
||||
else if (isalpha(*p))
|
||||
else if (isalpha(*p))
|
||||
guard += toupper(*p);
|
||||
else
|
||||
guard += "_";
|
||||
@@ -1719,7 +1719,7 @@ Module::writeHeader(const char *fn) {
|
||||
std::vector<Symbol *> exportedFuncs, externCFuncs;
|
||||
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
|
||||
m->symbolTable->GetMatchingFunctions(lIsExternC, &externCFuncs);
|
||||
|
||||
|
||||
// Get all of the struct, vector, and enumerant types used as function
|
||||
// parameters. These vectors may have repeats.
|
||||
std::vector<const StructType *> exportedStructTypes;
|
||||
@@ -1795,10 +1795,10 @@ Module::execPreprocessor(const char *infilename, llvm::raw_string_ostream *ostre
|
||||
#endif
|
||||
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs(new clang::DiagnosticIDs);
|
||||
#if defined(LLVM_3_1)
|
||||
clang::DiagnosticsEngine *diagEngine =
|
||||
clang::DiagnosticsEngine *diagEngine =
|
||||
new clang::DiagnosticsEngine(diagIDs, diagPrinter);
|
||||
#else
|
||||
clang::DiagnosticsEngine *diagEngine =
|
||||
clang::DiagnosticsEngine *diagEngine =
|
||||
new clang::DiagnosticsEngine(diagIDs, diagOptions, diagPrinter);
|
||||
#endif
|
||||
inst.setDiagnostics(diagEngine);
|
||||
@@ -1843,7 +1843,7 @@ Module::execPreprocessor(const char *infilename, llvm::raw_string_ostream *ostre
|
||||
headerOpts.Verbose = 1;
|
||||
for (int i = 0; i < (int)g->includePath.size(); ++i) {
|
||||
headerOpts.AddPath(g->includePath[i], clang::frontend::Angled,
|
||||
#if !defined(LLVM_3_3)
|
||||
#if !defined(LLVM_3_3)
|
||||
true /* is user supplied */,
|
||||
#endif
|
||||
false /* not a framework */,
|
||||
@@ -1884,7 +1884,7 @@ Module::execPreprocessor(const char *infilename, llvm::raw_string_ostream *ostre
|
||||
opts.addMacroDef("ISPC_MINOR_VERSION=3");
|
||||
|
||||
if (g->includeStdlib) {
|
||||
if (g->opt.disableAsserts)
|
||||
if (g->opt.disableAsserts)
|
||||
opts.addMacroDef("assert(x)=");
|
||||
else
|
||||
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
|
||||
// the form "sse2,avx-x2", return a vector of strings where each returned
|
||||
// string holds one of the targets from the given string.
|
||||
static std::vector<std::string>
|
||||
static std::vector<std::string>
|
||||
lExtractTargets(const char *target) {
|
||||
std::vector<std::string> targets;
|
||||
const char *tstart = target;
|
||||
@@ -1985,14 +1985,14 @@ struct FunctionTargetVariants {
|
||||
// Given the symbol table for a module, return a map from function names to
|
||||
// FunctionTargetVariants for each function that was defined with the
|
||||
// 'export' qualifier in ispc.
|
||||
static void
|
||||
lGetExportedFunctions(SymbolTable *symbolTable,
|
||||
static void
|
||||
lGetExportedFunctions(SymbolTable *symbolTable,
|
||||
std::map<std::string, FunctionTargetVariants> &functions) {
|
||||
std::vector<Symbol *> syms;
|
||||
symbolTable->GetMatchingFunctions(lSymbolIsExported, &syms);
|
||||
for (unsigned int i = 0; i < syms.size(); ++i) {
|
||||
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
|
||||
// files.
|
||||
static void
|
||||
lExtractAndRewriteGlobals(llvm::Module *module,
|
||||
lExtractAndRewriteGlobals(llvm::Module *module,
|
||||
std::vector<RewriteGlobalInfo> *globals) {
|
||||
llvm::Module::global_iterator iter;
|
||||
for (iter = module->global_begin(); iter != module->global_end(); ++iter) {
|
||||
@@ -2029,7 +2029,7 @@ lExtractAndRewriteGlobals(llvm::Module *module,
|
||||
llvm::Constant *init = gv->getInitializer();
|
||||
gv->setInitializer(NULL);
|
||||
|
||||
Symbol *sym =
|
||||
Symbol *sym =
|
||||
m->symbolTable->LookupVariable(gv->getName().str().c_str());
|
||||
Assert(sym != NULL);
|
||||
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
|
||||
// global
|
||||
llvm::GlobalVariable *newGlobal =
|
||||
llvm::GlobalVariable *newGlobal =
|
||||
new llvm::GlobalVariable(*module, type, gv->isConstant(),
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
initializer, gv->getName());
|
||||
@@ -2101,7 +2101,7 @@ lAddExtractedGlobals(llvm::Module *module,
|
||||
|
||||
|
||||
/** 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
|
||||
variant that was generated at compile time.
|
||||
|
||||
@@ -2119,7 +2119,7 @@ lAddExtractedGlobals(llvm::Module *module,
|
||||
*/
|
||||
static void
|
||||
lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
|
||||
llvm::Value *systemBestISAPtr, const std::string &name,
|
||||
llvm::Value *systemBestISAPtr, const std::string &name,
|
||||
FunctionTargetVariants &funcs) {
|
||||
// The llvm::Function pointers in funcs are pointers to functions in
|
||||
// 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)
|
||||
ftype = funcs.func[i]->getFunctionType();
|
||||
|
||||
targetFuncs[i] =
|
||||
llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage,
|
||||
targetFuncs[i] =
|
||||
llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage,
|
||||
funcs.func[i]->getName(), module);
|
||||
}
|
||||
|
||||
bool voidReturn = ftype->getReturnType()->isVoidTy();
|
||||
|
||||
// Now we can emit the definition of the dispatch function..
|
||||
llvm::Function *dispatchFunc =
|
||||
llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage,
|
||||
llvm::Function *dispatchFunc =
|
||||
llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage,
|
||||
name.c_str(), module);
|
||||
llvm::BasicBlock *bblock =
|
||||
llvm::BasicBlock *bblock =
|
||||
llvm::BasicBlock::Create(*g->ctx, "entry", dispatchFunc);
|
||||
|
||||
// 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);
|
||||
|
||||
// Now we can load the system's ISA enuemrant
|
||||
llvm::Value *systemISA =
|
||||
llvm::Value *systemISA =
|
||||
new llvm::LoadInst(systemBestISAPtr, "system_isa", bblock);
|
||||
|
||||
// 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
|
||||
// variant successfully--"is the system's ISA enuemrant value >=
|
||||
// the enumerant value of the current candidate?"
|
||||
llvm::Value *ok =
|
||||
llvm::Value *ok =
|
||||
llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGE,
|
||||
systemISA, LLVMInt32(i), "isa_ok", bblock);
|
||||
llvm::BasicBlock *callBBlock =
|
||||
llvm::BasicBlock *callBBlock =
|
||||
llvm::BasicBlock::Create(*g->ctx, "do_call", dispatchFunc);
|
||||
llvm::BasicBlock *nextBBlock =
|
||||
llvm::BasicBlock *nextBBlock =
|
||||
llvm::BasicBlock::Create(*g->ctx, "next_try", dispatchFunc);
|
||||
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
|
||||
// the target-specific function.
|
||||
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)
|
||||
args.push_back(argIter);
|
||||
if (voidReturn) {
|
||||
@@ -2200,8 +2200,8 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
|
||||
llvm::ReturnInst::Create(*g->ctx, callBBlock);
|
||||
}
|
||||
else {
|
||||
llvm::Value *retValue =
|
||||
llvm::CallInst::Create(targetFuncs[i], args, "ret_value",
|
||||
llvm::Value *retValue =
|
||||
llvm::CallInst::Create(targetFuncs[i], args, "ret_value",
|
||||
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.
|
||||
extern unsigned char builtins_bitcode_dispatch[];
|
||||
extern int builtins_bitcode_dispatch_length;
|
||||
AddBitcodeToModule(builtins_bitcode_dispatch,
|
||||
AddBitcodeToModule(builtins_bitcode_dispatch,
|
||||
builtins_bitcode_dispatch_length, module);
|
||||
|
||||
// Get pointers to things we need below
|
||||
llvm::Function *setFunc = module->getFunction("__set_system_isa");
|
||||
Assert(setFunc != NULL);
|
||||
llvm::Value *systemBestISAPtr =
|
||||
llvm::Value *systemBestISAPtr =
|
||||
module->getGlobalVariable("__system_best_isa", true);
|
||||
Assert(systemBestISAPtr != NULL);
|
||||
|
||||
@@ -2272,18 +2272,18 @@ lCreateDispatchModule(std::map<std::string, FunctionTargetVariants> &functions)
|
||||
|
||||
|
||||
int
|
||||
Module::CompileAndOutput(const char *srcFile,
|
||||
const char *arch,
|
||||
const char *cpu,
|
||||
const char *target,
|
||||
bool generatePIC,
|
||||
OutputType outputType,
|
||||
const char *outFileName,
|
||||
Module::CompileAndOutput(const char *srcFile,
|
||||
const char *arch,
|
||||
const char *cpu,
|
||||
const char *target,
|
||||
bool generatePIC,
|
||||
OutputType outputType,
|
||||
const char *outFileName,
|
||||
const char *headerFileName,
|
||||
const char *includeFileName,
|
||||
const char *depsFileName,
|
||||
const char *hostStubFileName,
|
||||
const char *devStubFileName)
|
||||
const char *devStubFileName)
|
||||
{
|
||||
if (target == NULL || strchr(target, ',') == NULL) {
|
||||
// We're only compiling to a single target
|
||||
@@ -2368,7 +2368,7 @@ Module::CompileAndOutput(const char *srcFile,
|
||||
std::vector<RewriteGlobalInfo> globals[Target::NUM_ISAS];
|
||||
int errorCount = 0;
|
||||
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))
|
||||
return 1;
|
||||
|
||||
@@ -2393,7 +2393,7 @@ Module::CompileAndOutput(const char *srcFile,
|
||||
|
||||
if (outFileName != NULL) {
|
||||
const char *isaName = g->target.GetISAString();
|
||||
std::string targetOutFileName =
|
||||
std::string targetOutFileName =
|
||||
lGetTargetFileName(outFileName, isaName);
|
||||
if (!m->writeOutput(outputType, targetOutFileName.c_str()))
|
||||
return 1;
|
||||
@@ -2412,7 +2412,7 @@ Module::CompileAndOutput(const char *srcFile,
|
||||
// we generate the dispatch module's functions...
|
||||
}
|
||||
|
||||
llvm::Module *dispatchModule =
|
||||
llvm::Module *dispatchModule =
|
||||
lCreateDispatchModule(exportedFunctions);
|
||||
|
||||
lAddExtractedGlobals(dispatchModule, globals);
|
||||
@@ -2434,7 +2434,7 @@ Module::CompileAndOutput(const char *srcFile,
|
||||
writeObjectFileOrAssembly(firstTargetMachine, dispatchModule,
|
||||
outputType, outFileName);
|
||||
}
|
||||
|
||||
|
||||
return errorCount > 0;
|
||||
}
|
||||
}
|
||||
|
||||
26
module.h
26
module.h
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
|
||||
/** Add a new global variable corresponding to the given Symbol to the
|
||||
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,
|
||||
Expr *initExpr, bool isConst,
|
||||
StorageClass storageClass, SourcePos pos);
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
/** Add a declaration of the function defined by the given function
|
||||
symbol to the module. */
|
||||
void AddFunctionDeclaration(const std::string &name,
|
||||
const FunctionType *ftype,
|
||||
const FunctionType *ftype,
|
||||
StorageClass sc, bool isInline, SourcePos pos);
|
||||
|
||||
/** 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
|
||||
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);
|
||||
|
||||
/** After a source file has been compiled, output can be generated in a
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
Bitcode, /** Generate LLVM IR bitcode output */
|
||||
Object, /** Generate a native object 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
|
||||
variables, and the types used by them. */
|
||||
Deps, /** generate dependencies */
|
||||
@@ -122,18 +122,18 @@ public:
|
||||
inclusion from C/C++ code with declarations of
|
||||
types and functions exported from the given ispc
|
||||
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
|
||||
get definitions of the builtins for the generic
|
||||
target.
|
||||
@return Number of errors encountered when compiling
|
||||
srcFile.
|
||||
*/
|
||||
static int CompileAndOutput(const char *srcFile, const char *arch,
|
||||
const char *cpu, const char *targets,
|
||||
bool generatePIC,
|
||||
OutputType outputType,
|
||||
const char *outFileName,
|
||||
static int CompileAndOutput(const char *srcFile, const char *arch,
|
||||
const char *cpu, const char *targets,
|
||||
bool generatePIC,
|
||||
OutputType outputType,
|
||||
const char *outFileName,
|
||||
const char *headerFileName,
|
||||
const char *includeFileName,
|
||||
const char *depsFileName,
|
||||
@@ -148,7 +148,7 @@ public:
|
||||
SymbolTable *symbolTable;
|
||||
|
||||
/** llvm Module object into which globals and functions are added. */
|
||||
llvm::Module *module;
|
||||
llvm::Module *module;
|
||||
|
||||
/** The diBuilder manages generating debugging information */
|
||||
llvm::DIBuilder *diBuilder;
|
||||
@@ -171,7 +171,7 @@ private:
|
||||
bool writeHostStub(const char *filename);
|
||||
bool writeObjectFileOrAssembly(OutputType outputType, const char *filename);
|
||||
static bool writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
|
||||
llvm::Module *module, OutputType outputType,
|
||||
llvm::Module *module, OutputType outputType,
|
||||
const char *outFileName);
|
||||
static bool writeBitcode(llvm::Module *module, const char *outFileName);
|
||||
|
||||
|
||||
4
opt.h
4
opt.h
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -43,7 +43,7 @@
|
||||
/** Optimize the functions in the given module, applying the specified
|
||||
level of optimization. optLevel zero corresponds to essentially no
|
||||
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);
|
||||
|
||||
|
||||
228
parse.yy
228
parse.yy
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -125,14 +125,14 @@ static const char *lBuiltinTokens[] = {
|
||||
"foreach_unique", "goto", "if", "in", "inline",
|
||||
"int", "int8", "int16", "int32", "int64", "launch", "new", "NULL",
|
||||
"print", "return", "signed", "sizeof", "static", "struct", "switch",
|
||||
"sync", "task", "true", "typedef", "uniform", "unmasked", "unsigned",
|
||||
"varying", "void", "while", NULL
|
||||
"sync", "task", "true", "typedef", "uniform", "unmasked", "unsigned",
|
||||
"varying", "void", "while", NULL
|
||||
};
|
||||
|
||||
static const char *lParamListTokens[] = {
|
||||
"bool", "const", "double", "enum", "false", "float", "int",
|
||||
"int8", "int16", "int32", "int64", "signed", "struct", "true",
|
||||
"uniform", "unsigned", "varying", "void", NULL
|
||||
"uniform", "unsigned", "varying", "void", NULL
|
||||
};
|
||||
|
||||
struct ForeachDimension {
|
||||
@@ -179,27 +179,27 @@ struct ForeachDimension {
|
||||
}
|
||||
|
||||
|
||||
%token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT
|
||||
%token TOKEN_INT64_CONSTANT TOKEN_UINT64_CONSTANT
|
||||
%token TOKEN_INT32DOTDOTDOT_CONSTANT TOKEN_UINT32DOTDOTDOT_CONSTANT
|
||||
%token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT
|
||||
%token TOKEN_INT64_CONSTANT TOKEN_UINT64_CONSTANT
|
||||
%token TOKEN_INT32DOTDOTDOT_CONSTANT TOKEN_UINT32DOTDOTDOT_CONSTANT
|
||||
%token TOKEN_INT64DOTDOTDOT_CONSTANT TOKEN_UINT64DOTDOTDOT_CONSTANT
|
||||
%token TOKEN_FLOAT_CONSTANT TOKEN_STRING_C_LITERAL
|
||||
%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_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_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_AND_ASSIGN TOKEN_OR_ASSIGN TOKEN_XOR_ASSIGN
|
||||
%token TOKEN_SIZEOF TOKEN_NEW TOKEN_DELETE TOKEN_IN
|
||||
|
||||
%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_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_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_FOR TOKEN_GOTO TOKEN_CONTINUE TOKEN_BREAK TOKEN_RETURN
|
||||
%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 <declaration> declaration parameter_declaration
|
||||
%type <declarators> init_declarator_list
|
||||
%type <declarators> init_declarator_list
|
||||
%type <declarationList> parameter_list parameter_type_list
|
||||
%type <declarator> declarator pointer reference
|
||||
%type <declarator> init_declarator direct_declarator struct_declarator
|
||||
@@ -244,10 +244,10 @@ struct ForeachDimension {
|
||||
|
||||
%type <typeQualifier> type_qualifier type_qualifier_list
|
||||
%type <storageClass> storage_class_specifier
|
||||
%type <declSpecs> declaration_specifiers
|
||||
%type <declSpecs> declaration_specifiers
|
||||
|
||||
%type <stringVal> string_constant
|
||||
%type <constCharPtr> struct_or_union_name enum_identifier goto_identifier
|
||||
%type <stringVal> string_constant
|
||||
%type <constCharPtr> struct_or_union_name enum_identifier goto_identifier
|
||||
%type <constCharPtr> foreach_unique_identifier
|
||||
|
||||
%type <intVal> int_constant soa_width_specifier rate_qualified_new
|
||||
@@ -277,7 +277,7 @@ primary_expression
|
||||
Symbol *s = m->symbolTable->LookupVariable(name);
|
||||
$$ = NULL;
|
||||
if (s)
|
||||
$$ = new SymbolExpr(s, @1);
|
||||
$$ = new SymbolExpr(s, @1);
|
||||
else {
|
||||
std::vector<Symbol *> funs;
|
||||
m->symbolTable->LookupFunction(name, &funs);
|
||||
@@ -285,7 +285,7 @@ primary_expression
|
||||
$$ = new FunctionSymbolExpr(name, funs, @1);
|
||||
}
|
||||
if ($$ == NULL) {
|
||||
std::vector<std::string> alternates =
|
||||
std::vector<std::string> alternates =
|
||||
m->symbolTable->ClosestVariableOrFunctionMatch(name);
|
||||
std::string alts = lGetAlternates(alternates);
|
||||
Error(@1, "Undeclared symbol \"%s\".%s", name, alts.c_str());
|
||||
@@ -293,23 +293,23 @@ primary_expression
|
||||
}
|
||||
| TOKEN_INT32_CONSTANT {
|
||||
$$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
|
||||
(int32_t)yylval.intVal, @1);
|
||||
(int32_t)yylval.intVal, @1);
|
||||
}
|
||||
| TOKEN_UINT32_CONSTANT {
|
||||
$$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
|
||||
(uint32_t)yylval.intVal, @1);
|
||||
(uint32_t)yylval.intVal, @1);
|
||||
}
|
||||
| TOKEN_INT64_CONSTANT {
|
||||
$$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
|
||||
(int64_t)yylval.intVal, @1);
|
||||
(int64_t)yylval.intVal, @1);
|
||||
}
|
||||
| TOKEN_UINT64_CONSTANT {
|
||||
$$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
|
||||
(uint64_t)yylval.intVal, @1);
|
||||
(uint64_t)yylval.intVal, @1);
|
||||
}
|
||||
| TOKEN_FLOAT_CONSTANT {
|
||||
$$ = new ConstExpr(AtomicType::UniformFloat->GetAsConstType(),
|
||||
(float)yylval.floatVal, @1);
|
||||
(float)yylval.floatVal, @1);
|
||||
}
|
||||
| TOKEN_TRUE {
|
||||
$$ = new ConstExpr(AtomicType::UniformBool->GetAsConstType(), true, @1);
|
||||
@@ -328,7 +328,7 @@ primary_expression
|
||||
|
||||
launch_expression
|
||||
: TOKEN_LAUNCH postfix_expression '(' argument_expression_list ')'
|
||||
{
|
||||
{
|
||||
ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @2);
|
||||
$$ = 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); }
|
||||
|
||||
| TOKEN_LAUNCH '<' postfix_expression '(' argument_expression_list ')' '>'
|
||||
{
|
||||
{
|
||||
Error(Union(@2, @7), "\"launch\" expressions no longer take '<' '>' "
|
||||
"around function call expression.");
|
||||
$$ = NULL;
|
||||
@@ -412,21 +412,21 @@ argument_expression_list
|
||||
|
||||
unary_expression
|
||||
: funcall_expression
|
||||
| TOKEN_INC_OP unary_expression
|
||||
| TOKEN_INC_OP unary_expression
|
||||
{ $$ = 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)); }
|
||||
| '&' unary_expression
|
||||
{ $$ = new AddressOfExpr($2, Union(@1, @2)); }
|
||||
| '*' unary_expression
|
||||
{ $$ = new PtrDerefExpr($2, Union(@1, @2)); }
|
||||
| '+' cast_expression
|
||||
| '+' cast_expression
|
||||
{ $$ = $2; }
|
||||
| '-' cast_expression
|
||||
| '-' cast_expression
|
||||
{ $$ = new UnaryExpr(UnaryExpr::Negate, $2, Union(@1, @2)); }
|
||||
| '~' cast_expression
|
||||
| '~' cast_expression
|
||||
{ $$ = new UnaryExpr(UnaryExpr::BitNot, $2, Union(@1, @2)); }
|
||||
| '!' cast_expression
|
||||
| '!' cast_expression
|
||||
{ $$ = new UnaryExpr(UnaryExpr::LogicalNot, $2, Union(@1, @2)); }
|
||||
| TOKEN_SIZEOF unary_expression
|
||||
{ $$ = new SizeOfExpr($2, Union(@1, @2)); }
|
||||
@@ -438,7 +438,7 @@ cast_expression
|
||||
: unary_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
|
||||
: declaration
|
||||
{
|
||||
if ($1 == NULL) {
|
||||
AssertPos(@1, m->errorCount > 0);
|
||||
@@ -810,11 +810,11 @@ init_declarator_list
|
||||
|
||||
init_declarator
|
||||
: declarator
|
||||
| declarator '=' initializer
|
||||
| declarator '=' initializer
|
||||
{
|
||||
if ($1 != NULL)
|
||||
$1->initExpr = $3;
|
||||
$$ = $1;
|
||||
$1->initExpr = $3;
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
@@ -829,7 +829,7 @@ type_specifier
|
||||
: atomic_var_type_specifier { $$ = $1; }
|
||||
| TOKEN_TYPE_NAME
|
||||
{
|
||||
const Type *t = m->symbolTable->LookupType(yytext);
|
||||
const Type *t = m->symbolTable->LookupType(yytext);
|
||||
$$ = t;
|
||||
}
|
||||
| struct_or_union_specifier { $$ = $1; }
|
||||
@@ -837,7 +837,7 @@ type_specifier
|
||||
;
|
||||
|
||||
type_specifier_list
|
||||
: type_specifier
|
||||
: type_specifier
|
||||
{
|
||||
if ($1 == NULL)
|
||||
$$ = NULL;
|
||||
@@ -883,8 +883,8 @@ struct_or_union_name
|
||||
|
||||
struct_or_union_and_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) {
|
||||
st = new UndefinedStructType($2, Variability::Unbound, false, @2);
|
||||
m->symbolTable->AddType($2, st, @2);
|
||||
@@ -905,7 +905,7 @@ struct_or_union_and_name
|
||||
|
||||
struct_or_union_specifier
|
||||
: struct_or_union_and_name
|
||||
| struct_or_union_and_name '{' struct_declaration_list '}'
|
||||
| struct_or_union_and_name '{' struct_declaration_list '}'
|
||||
{
|
||||
if ($3 != NULL) {
|
||||
llvm::SmallVector<const Type *, 8> elementTypes;
|
||||
@@ -924,7 +924,7 @@ struct_or_union_specifier
|
||||
else
|
||||
$$ = NULL;
|
||||
}
|
||||
| struct_or_union '{' struct_declaration_list '}'
|
||||
| struct_or_union '{' struct_declaration_list '}'
|
||||
{
|
||||
if ($3 != NULL) {
|
||||
llvm::SmallVector<const Type *, 8> elementTypes;
|
||||
@@ -938,7 +938,7 @@ struct_or_union_specifier
|
||||
else
|
||||
$$ = NULL;
|
||||
}
|
||||
| struct_or_union '{' '}'
|
||||
| struct_or_union '{' '}'
|
||||
{
|
||||
llvm::SmallVector<const Type *, 8> elementTypes;
|
||||
llvm::SmallVector<std::string, 8> elementNames;
|
||||
@@ -946,7 +946,7 @@ struct_or_union_specifier
|
||||
$$ = new StructType("", elementTypes, elementNames, elementPositions,
|
||||
false, Variability::Unbound, @1);
|
||||
}
|
||||
| struct_or_union_and_name '{' '}'
|
||||
| struct_or_union_and_name '{' '}'
|
||||
{
|
||||
llvm::SmallVector<const Type *, 8> elementTypes;
|
||||
llvm::SmallVector<std::string, 8> elementNames;
|
||||
@@ -963,18 +963,18 @@ struct_or_union_specifier
|
||||
;
|
||||
|
||||
struct_or_union
|
||||
: TOKEN_STRUCT
|
||||
: TOKEN_STRUCT
|
||||
;
|
||||
|
||||
struct_declaration_list
|
||||
: struct_declaration
|
||||
{
|
||||
: struct_declaration
|
||||
{
|
||||
std::vector<StructDeclaration *> *sdl = new std::vector<StructDeclaration *>;
|
||||
if ($1 != NULL)
|
||||
sdl->push_back($1);
|
||||
$$ = sdl;
|
||||
}
|
||||
| struct_declaration_list struct_declaration
|
||||
| struct_declaration_list struct_declaration
|
||||
{
|
||||
std::vector<StructDeclaration *> *sdl = (std::vector<StructDeclaration *> *)$1;
|
||||
if (sdl == NULL) {
|
||||
@@ -988,7 +988,7 @@ struct_declaration_list
|
||||
;
|
||||
|
||||
struct_declaration
|
||||
: specifier_qualifier_list struct_declarator_list ';'
|
||||
: specifier_qualifier_list struct_declarator_list ';'
|
||||
{ $$ = ($1 != NULL && $2 != NULL) ? new StructDeclaration($1, $2) : NULL; }
|
||||
;
|
||||
|
||||
@@ -996,7 +996,7 @@ specifier_qualifier_list
|
||||
: type_specifier specifier_qualifier_list
|
||||
| type_specifier
|
||||
| short_vec_specifier
|
||||
| type_qualifier specifier_qualifier_list
|
||||
| type_qualifier specifier_qualifier_list
|
||||
{
|
||||
if ($2 != NULL) {
|
||||
if ($1 == TYPEQUAL_UNIFORM) {
|
||||
@@ -1033,7 +1033,7 @@ specifier_qualifier_list
|
||||
$2->ResolveUnboundVariability(Variability::Varying)->GetString().c_str());
|
||||
$$ = $2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($1 == TYPEQUAL_INLINE) {
|
||||
Error(@1, "\"inline\" qualifier is illegal outside of "
|
||||
"function declarations.");
|
||||
@@ -1059,7 +1059,7 @@ specifier_qualifier_list
|
||||
}
|
||||
else {
|
||||
if (m->errorCount == 0)
|
||||
Error(@1, "Lost type qualifier in parser.");
|
||||
Error(@1, "Lost type qualifier in parser.");
|
||||
$$ = NULL;
|
||||
}
|
||||
}
|
||||
@@ -1067,14 +1067,14 @@ specifier_qualifier_list
|
||||
|
||||
|
||||
struct_declarator_list
|
||||
: struct_declarator
|
||||
: struct_declarator
|
||||
{
|
||||
std::vector<Declarator *> *sdl = new std::vector<Declarator *>;
|
||||
if ($1 != NULL)
|
||||
sdl->push_back($1);
|
||||
$$ = sdl;
|
||||
}
|
||||
| struct_declarator_list ',' struct_declarator
|
||||
| struct_declarator_list ',' struct_declarator
|
||||
{
|
||||
std::vector<Declarator *> *sdl = (std::vector<Declarator *> *)$1;
|
||||
if (sdl == NULL) {
|
||||
@@ -1099,19 +1099,19 @@ enum_identifier
|
||||
: TOKEN_IDENTIFIER { $$ = strdup(yytext); }
|
||||
|
||||
enum_specifier
|
||||
: TOKEN_ENUM '{' enumerator_list '}'
|
||||
: TOKEN_ENUM '{' enumerator_list '}'
|
||||
{
|
||||
$$ = lCreateEnumType(NULL, $3, @1);
|
||||
}
|
||||
| TOKEN_ENUM enum_identifier '{' enumerator_list '}'
|
||||
| TOKEN_ENUM enum_identifier '{' enumerator_list '}'
|
||||
{
|
||||
$$ = lCreateEnumType($2, $4, @2);
|
||||
}
|
||||
| TOKEN_ENUM '{' enumerator_list ',' '}'
|
||||
| TOKEN_ENUM '{' enumerator_list ',' '}'
|
||||
{
|
||||
$$ = lCreateEnumType(NULL, $3, @1);
|
||||
}
|
||||
| TOKEN_ENUM enum_identifier '{' enumerator_list ',' '}'
|
||||
| TOKEN_ENUM enum_identifier '{' enumerator_list ',' '}'
|
||||
{
|
||||
$$ = lCreateEnumType($2, $4, @2);
|
||||
}
|
||||
@@ -1138,12 +1138,12 @@ enum_specifier
|
||||
;
|
||||
|
||||
enumerator_list
|
||||
: enumerator
|
||||
: enumerator
|
||||
{
|
||||
if ($1 == NULL)
|
||||
$$ = NULL;
|
||||
else {
|
||||
std::vector<Symbol *> *el = new std::vector<Symbol *>;
|
||||
std::vector<Symbol *> *el = new std::vector<Symbol *>;
|
||||
el->push_back($1);
|
||||
$$ = el;
|
||||
}
|
||||
@@ -1198,7 +1198,7 @@ type_qualifier_list
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| type_qualifier_list type_qualifier
|
||||
| type_qualifier_list type_qualifier
|
||||
{
|
||||
$$ = $1 | $2;
|
||||
}
|
||||
@@ -1243,9 +1243,9 @@ direct_declarator
|
||||
d->name = yytext;
|
||||
$$ = d;
|
||||
}
|
||||
| '(' declarator ')'
|
||||
| '(' declarator ')'
|
||||
{
|
||||
$$ = $2;
|
||||
$$ = $2;
|
||||
}
|
||||
| direct_declarator '[' constant_expression ']'
|
||||
{
|
||||
@@ -1310,9 +1310,9 @@ direct_declarator
|
||||
|
||||
|
||||
pointer
|
||||
: '*'
|
||||
: '*'
|
||||
{
|
||||
$$ = new Declarator(DK_POINTER, @1);
|
||||
$$ = new Declarator(DK_POINTER, @1);
|
||||
}
|
||||
| '*' type_qualifier_list
|
||||
{
|
||||
@@ -1337,9 +1337,9 @@ pointer
|
||||
|
||||
|
||||
reference
|
||||
: '&'
|
||||
: '&'
|
||||
{
|
||||
$$ = new Declarator(DK_REFERENCE, @1);
|
||||
$$ = new Declarator(DK_REFERENCE, @1);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -1375,10 +1375,10 @@ parameter_list
|
||||
parameter_declaration
|
||||
: declaration_specifiers declarator
|
||||
{
|
||||
$$ = new Declaration($1, $2);
|
||||
$$ = new Declaration($1, $2);
|
||||
}
|
||||
| declaration_specifiers declarator '=' initializer
|
||||
{
|
||||
{
|
||||
if ($1 != NULL && $2 != NULL) {
|
||||
$2->initExpr = $4;
|
||||
$$ = new Declaration($1, $2);
|
||||
@@ -1398,11 +1398,11 @@ parameter_declaration
|
||||
if ($1 == NULL)
|
||||
$$ = NULL;
|
||||
else
|
||||
$$ = new Declaration($1);
|
||||
$$ = new Declaration($1);
|
||||
}
|
||||
;
|
||||
|
||||
/* K&R?
|
||||
/* K&R?
|
||||
identifier_list
|
||||
: IDENTIFIER
|
||||
| identifier_list ',' IDENTIFIER
|
||||
@@ -1588,9 +1588,9 @@ labeled_statement
|
||||
$$ = new LabeledStmt($1, $3, @1);
|
||||
}
|
||||
| TOKEN_CASE constant_expression ':' statement
|
||||
{
|
||||
{
|
||||
int value;
|
||||
if ($2 != NULL &&
|
||||
if ($2 != NULL &&
|
||||
lGetConstantInt($2, &value, @2, "Case statement value")) {
|
||||
$$ = new CaseStmt(value, $4, Union(@1, @2));
|
||||
}
|
||||
@@ -1700,19 +1700,19 @@ foreach_active_identifier
|
||||
integer_dotdotdot
|
||||
: TOKEN_INT32DOTDOTDOT_CONSTANT {
|
||||
$$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
|
||||
(int32_t)yylval.intVal, @1);
|
||||
(int32_t)yylval.intVal, @1);
|
||||
}
|
||||
| TOKEN_UINT32DOTDOTDOT_CONSTANT {
|
||||
$$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
|
||||
(uint32_t)yylval.intVal, @1);
|
||||
(uint32_t)yylval.intVal, @1);
|
||||
}
|
||||
| TOKEN_INT64DOTDOTDOT_CONSTANT {
|
||||
$$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
|
||||
(int64_t)yylval.intVal, @1);
|
||||
(int64_t)yylval.intVal, @1);
|
||||
}
|
||||
| TOKEN_UINT64DOTDOTDOT_CONSTANT {
|
||||
$$ = 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
|
||||
: TOKEN_FOREACH_UNIQUE { m->symbolTable->PushScope(); }
|
||||
;
|
||||
|
||||
|
||||
foreach_unique_identifier
|
||||
: TOKEN_IDENTIFIER { $$ = yylval.stringVal->c_str(); }
|
||||
;
|
||||
@@ -1764,11 +1764,11 @@ iteration_statement
|
||||
| TOKEN_CDO statement TOKEN_WHILE '(' expression ')' ';'
|
||||
{ $$ = new DoStmt($5, $2, true, @1); }
|
||||
| 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();
|
||||
}
|
||||
| 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();
|
||||
}
|
||||
| cfor_scope '(' for_init_statement for_test ')' statement
|
||||
@@ -1847,7 +1847,7 @@ iteration_statement
|
||||
m->symbolTable->PopScope();
|
||||
}
|
||||
| foreach_unique_scope '(' foreach_unique_identifier TOKEN_IN
|
||||
expression ')'
|
||||
expression ')'
|
||||
{
|
||||
Expr *expr = $5;
|
||||
const Type *type;
|
||||
@@ -1905,11 +1905,11 @@ unmasked_statement
|
||||
print_statement
|
||||
: TOKEN_PRINT '(' string_constant ')' ';'
|
||||
{
|
||||
$$ = new PrintStmt(*$3, NULL, @1);
|
||||
$$ = new PrintStmt(*$3, NULL, @1);
|
||||
}
|
||||
| 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)
|
||||
m->AddExportedTypes(*$3);
|
||||
}
|
||||
| declaration
|
||||
{
|
||||
| declaration
|
||||
{
|
||||
if ($1 != NULL)
|
||||
for (unsigned int i = 0; i < $1->declarators.size(); ++i)
|
||||
lAddDeclaration($1->declSpecs, $1->declarators[i]);
|
||||
@@ -1944,14 +1944,14 @@ external_declaration
|
||||
;
|
||||
|
||||
function_definition
|
||||
: declaration_specifiers declarator
|
||||
: declaration_specifiers declarator
|
||||
{
|
||||
lAddDeclaration($1, $2);
|
||||
lAddFunctionParams($2);
|
||||
lAddFunctionParams($2);
|
||||
lAddMaskToSymbolTable(@2);
|
||||
if ($1->typeQualifiers & TYPEQUAL_TASK)
|
||||
lAddThreadIndexCountToSymbolTable(@2);
|
||||
}
|
||||
}
|
||||
compound_statement
|
||||
{
|
||||
if ($2 != NULL) {
|
||||
@@ -1970,7 +1970,7 @@ function_definition
|
||||
m->symbolTable->PopScope(); // push in lAddFunctionParams();
|
||||
}
|
||||
/* function with no declared return type??
|
||||
func(...)
|
||||
func(...)
|
||||
| declarator { lAddFunctionParams($1); } compound_statement
|
||||
{
|
||||
m->AddFunction(new DeclSpecs(XXX, $1, $3);
|
||||
@@ -2002,34 +2002,34 @@ lYYTNameErr (char *yyres, const char *yystr)
|
||||
else
|
||||
return yystpcpy(yyres, n.c_str()) - yyres;
|
||||
}
|
||||
|
||||
|
||||
if (*yystr == '"')
|
||||
{
|
||||
YYSIZE_T yyn = 0;
|
||||
char const *yyp = yystr;
|
||||
|
||||
for (;;)
|
||||
switch (*++yyp)
|
||||
{
|
||||
case '\'':
|
||||
case ',':
|
||||
goto do_not_strip_quotes;
|
||||
switch (*++yyp)
|
||||
{
|
||||
case '\'':
|
||||
case ',':
|
||||
goto do_not_strip_quotes;
|
||||
|
||||
case '\\':
|
||||
if (*++yyp != '\\')
|
||||
goto do_not_strip_quotes;
|
||||
/* Fall through. */
|
||||
default:
|
||||
if (yyres)
|
||||
yyres[yyn] = *yyp;
|
||||
yyn++;
|
||||
break;
|
||||
case '\\':
|
||||
if (*++yyp != '\\')
|
||||
goto do_not_strip_quotes;
|
||||
/* Fall through. */
|
||||
default:
|
||||
if (yyres)
|
||||
yyres[yyn] = *yyp;
|
||||
yyn++;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
if (yyres)
|
||||
yyres[yyn] = '\0';
|
||||
return yyn;
|
||||
}
|
||||
case '"':
|
||||
if (yyres)
|
||||
yyres[yyn] = '\0';
|
||||
return yyn;
|
||||
}
|
||||
do_not_strip_quotes: ;
|
||||
}
|
||||
|
||||
@@ -2085,7 +2085,7 @@ lAddDeclaration(DeclSpecs *ds, Declarator *decl) {
|
||||
}
|
||||
|
||||
decl->type = decl->type->ResolveUnboundVariability(Variability::Varying);
|
||||
|
||||
|
||||
const FunctionType *ft = CastType<FunctionType>(decl->type);
|
||||
if (ft != NULL) {
|
||||
bool isInline = (ds->typeQualifiers & TYPEQUAL_INLINE);
|
||||
@@ -2113,7 +2113,7 @@ lAddFunctionParams(Declarator *decl) {
|
||||
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)
|
||||
decl = decl->child;
|
||||
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
|
||||
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
|
||||
in the source file will already have ConstExpr * set; we just need
|
||||
to set the values for the others here.
|
||||
*/
|
||||
static void
|
||||
lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
|
||||
lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
|
||||
const EnumType *enumType) {
|
||||
enumType = enumType->GetAsConstType();
|
||||
enumType = enumType->GetAsUniformType();
|
||||
@@ -2304,7 +2304,7 @@ lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
|
||||
AssertPos(enums[i]->pos, enums[i]->constValue != NULL);
|
||||
}
|
||||
else {
|
||||
enums[i]->constValue = new ConstExpr(enumType, nextVal++,
|
||||
enums[i]->constValue = new ConstExpr(enumType, nextVal++,
|
||||
enums[i]->pos);
|
||||
}
|
||||
}
|
||||
|
||||
294
stmt.cpp
294
stmt.cpp
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -81,18 +81,18 @@ Stmt::Optimize() {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ExprStmt
|
||||
|
||||
ExprStmt::ExprStmt(Expr *e, SourcePos p)
|
||||
ExprStmt::ExprStmt(Expr *e, SourcePos p)
|
||||
: Stmt(p) {
|
||||
expr = e;
|
||||
}
|
||||
|
||||
void
|
||||
ExprStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
ctx->SetDebugPos(pos);
|
||||
if (expr)
|
||||
if (expr)
|
||||
expr->GetValue(ctx);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ ExprStmt::TypeCheck() {
|
||||
|
||||
void
|
||||
ExprStmt::Print(int indent) const {
|
||||
if (!expr)
|
||||
if (!expr)
|
||||
return;
|
||||
|
||||
printf("%*c", indent, ' ');
|
||||
@@ -141,11 +141,11 @@ lHasUnsizedArrays(const Type *type) {
|
||||
else
|
||||
return lHasUnsizedArrays(at->GetElementType());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
DeclStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
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
|
||||
// that it persists across function calls
|
||||
sym->storagePtr =
|
||||
new llvm::GlobalVariable(*m->module, llvmType,
|
||||
new llvm::GlobalVariable(*m->module, llvmType,
|
||||
sym->type->IsConstType(),
|
||||
llvm::GlobalValue::InternalLinkage, cinit,
|
||||
llvm::Twine("static.") +
|
||||
llvm::Twine(sym->pos.first_line) +
|
||||
llvm::Twine(sym->pos.first_line) +
|
||||
llvm::Twine(".") + sym->name.c_str());
|
||||
// Tell the FunctionEmitContext about the variable
|
||||
// Tell the FunctionEmitContext about the variable
|
||||
ctx->EmitVariableDebugInfo(sym);
|
||||
}
|
||||
else {
|
||||
@@ -282,7 +282,7 @@ DeclStmt::Optimize() {
|
||||
// computing array sizes from non-trivial expressions is
|
||||
// consequently limited.
|
||||
Symbol *sym = vars[i].sym;
|
||||
if (sym->type && sym->type->IsConstType() &&
|
||||
if (sym->type && sym->type->IsConstType() &&
|
||||
Type::Equal(init->GetType(), sym->type))
|
||||
sym->constValue = dynamic_cast<ConstExpr *>(init);
|
||||
}
|
||||
@@ -329,7 +329,7 @@ DeclStmt::Print(int indent) const {
|
||||
printf("%*cDecl Stmt:", indent, ' ');
|
||||
pos.Print();
|
||||
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->type->GetString().c_str());
|
||||
if (vars[i].init != NULL) {
|
||||
@@ -351,8 +351,8 @@ DeclStmt::EstimateCost() const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IfStmt
|
||||
|
||||
IfStmt::IfStmt(Expr *t, Stmt *ts, Stmt *fs, bool checkCoherence, SourcePos p)
|
||||
: Stmt(p), test(t), trueStmts(ts), falseStmts(fs),
|
||||
IfStmt::IfStmt(Expr *t, Stmt *ts, Stmt *fs, bool checkCoherence, SourcePos p)
|
||||
: Stmt(p), test(t), trueStmts(ts), falseStmts(fs),
|
||||
doAllCheck(checkCoherence &&
|
||||
!g->opt.disableCoherentControlFlow) {
|
||||
}
|
||||
@@ -399,9 +399,9 @@ IfStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
// 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
|
||||
// dereference NULL pointers in the below...
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
if (!test)
|
||||
if (!test)
|
||||
return;
|
||||
const Type *testType = test->GetType();
|
||||
if (!testType)
|
||||
@@ -433,7 +433,7 @@ IfStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
// Emit code for the 'true' case
|
||||
ctx->SetCurrentBasicBlock(bthen);
|
||||
lEmitIfStatements(ctx, trueStmts, "true");
|
||||
if (ctx->GetCurrentBasicBlock())
|
||||
if (ctx->GetCurrentBasicBlock())
|
||||
ctx->BranchInst(bexit);
|
||||
|
||||
// Emit code for the 'false' case
|
||||
@@ -466,10 +466,10 @@ IfStmt::TypeCheck() {
|
||||
if (test != NULL) {
|
||||
const Type *testType = test->GetType();
|
||||
if (testType != NULL) {
|
||||
bool isUniform = (testType->IsUniformType() &&
|
||||
bool isUniform = (testType->IsUniformType() &&
|
||||
!g->opt.disableUniformControlFlow);
|
||||
test = TypeConvertExpr(test, isUniform ? AtomicType::UniformBool :
|
||||
AtomicType::VaryingBool,
|
||||
test = TypeConvertExpr(test, isUniform ? AtomicType::UniformBool :
|
||||
AtomicType::VaryingBool,
|
||||
"\"if\" statement test");
|
||||
if (test == 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,
|
||||
with the mask set appropriately before running each one.
|
||||
with the mask set appropriately before running each one.
|
||||
*/
|
||||
void
|
||||
IfStmt::emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||
IfStmt::emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||
llvm::Value *test) const {
|
||||
if (trueStmts) {
|
||||
ctx->SetInternalMaskAnd(oldMask, test);
|
||||
lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements");
|
||||
// under varying control flow,, returns can't stop instruction
|
||||
// emission, so this better be non-NULL...
|
||||
AssertPos(ctx->GetDebugPos(), ctx->GetCurrentBasicBlock());
|
||||
AssertPos(ctx->GetDebugPos(), ctx->GetCurrentBasicBlock());
|
||||
}
|
||||
if (falseStmts) {
|
||||
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 *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());
|
||||
ctx->BranchInst(bAllOn, bMixedOn, maskAllQ);
|
||||
|
||||
// Emit code for the 'mask all on' case
|
||||
ctx->SetCurrentBasicBlock(bAllOn);
|
||||
emitMaskAllOn(ctx, ltest, bDone);
|
||||
|
||||
|
||||
// And emit code for the mixed mask case
|
||||
ctx->SetCurrentBasicBlock(bMixedOn);
|
||||
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
|
||||
// for the 'all lanes' off case.
|
||||
int trueFalseCost = (::EstimateCost(trueStmts) +
|
||||
int trueFalseCost = (::EstimateCost(trueStmts) +
|
||||
::EstimateCost(falseStmts));
|
||||
bool costIsAcceptable = (trueFalseCost <
|
||||
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).",
|
||||
::EstimateCost(trueStmts), (int)SafeToRunWithMaskAllOff(trueStmts),
|
||||
::EstimateCost(falseStmts), (int)SafeToRunWithMaskAllOff(falseStmts));
|
||||
|
||||
|
||||
if (safeToRunWithAllLanesOff &&
|
||||
(costIsAcceptable || g->opt.disableCoherentControlFlow)) {
|
||||
ctx->StartVaryingIf(oldMask);
|
||||
@@ -612,7 +612,7 @@ IfStmt::emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *ltest) const {
|
||||
mask is all on going into the 'if'.
|
||||
*/
|
||||
void
|
||||
IfStmt::emitMaskAllOn(FunctionEmitContext *ctx, llvm::Value *ltest,
|
||||
IfStmt::emitMaskAllOn(FunctionEmitContext *ctx, llvm::Value *ltest,
|
||||
llvm::BasicBlock *bDone) const {
|
||||
// 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
|
||||
@@ -682,7 +682,7 @@ IfStmt::emitMaskAllOn(FunctionEmitContext *ctx, llvm::Value *ltest,
|
||||
on/off going into it.
|
||||
*/
|
||||
void
|
||||
IfStmt::emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||
IfStmt::emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||
llvm::Value *ltest, llvm::BasicBlock *bDone) const {
|
||||
ctx->StartVaryingIf(oldMask);
|
||||
llvm::BasicBlock *bNext = ctx->CreateBasicBlock("safe_if_after_true");
|
||||
@@ -699,7 +699,7 @@ IfStmt::emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||
ctx->SetCurrentBasicBlock(bRunTrue);
|
||||
if (trueStmts != NULL)
|
||||
lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements");
|
||||
AssertPos(pos, ctx->GetCurrentBasicBlock());
|
||||
AssertPos(pos, ctx->GetCurrentBasicBlock());
|
||||
ctx->BranchInst(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
|
||||
look like a 'uniform' loop needs to have code emitted to do all of the
|
||||
lane management stuff if this is the case.
|
||||
*/
|
||||
*/
|
||||
static bool
|
||||
lHasVaryingBreakOrContinue(Stmt *stmt) {
|
||||
VaryingBCCheckInfo info;
|
||||
@@ -810,8 +810,8 @@ lHasVaryingBreakOrContinue(Stmt *stmt) {
|
||||
}
|
||||
|
||||
|
||||
DoStmt::DoStmt(Expr *t, Stmt *s, bool cc, SourcePos p)
|
||||
: Stmt(p), testExpr(t), bodyStmts(s),
|
||||
DoStmt::DoStmt(Expr *t, Stmt *s, bool cc, SourcePos p)
|
||||
: Stmt(p), testExpr(t), bodyStmts(s),
|
||||
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 {
|
||||
// Check for things that could be NULL due to earlier errors during
|
||||
// compilation.
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
if (!testExpr || !testExpr->GetType())
|
||||
if (!testExpr || !testExpr->GetType())
|
||||
return;
|
||||
|
||||
bool uniformTest = testExpr->GetType()->IsUniformType();
|
||||
@@ -984,15 +984,15 @@ DoStmt::Print(int indent) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ForStmt
|
||||
|
||||
ForStmt::ForStmt(Stmt *i, Expr *t, Stmt *s, Stmt *st, bool cc, SourcePos p)
|
||||
: Stmt(p), init(i), test(t), step(s), stmts(st),
|
||||
ForStmt::ForStmt(Stmt *i, Expr *t, Stmt *s, Stmt *st, bool cc, SourcePos p)
|
||||
: Stmt(p), init(i), test(t), step(s), stmts(st),
|
||||
doCoherentCheck(cc && !g->opt.disableCoherentControlFlow) {
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ForStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
llvm::BasicBlock *btest = ctx->CreateBasicBlock("for_test");
|
||||
@@ -1176,14 +1176,14 @@ ForStmt::Print(int indent) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// BreakStmt
|
||||
|
||||
BreakStmt::BreakStmt(SourcePos p)
|
||||
BreakStmt::BreakStmt(SourcePos p)
|
||||
: Stmt(p) {
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BreakStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
ctx->SetDebugPos(pos);
|
||||
@@ -1214,14 +1214,14 @@ BreakStmt::Print(int indent) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ContinueStmt
|
||||
|
||||
ContinueStmt::ContinueStmt(SourcePos p)
|
||||
ContinueStmt::ContinueStmt(SourcePos p)
|
||||
: Stmt(p) {
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContinueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
ctx->SetDebugPos(pos);
|
||||
@@ -1252,9 +1252,9 @@ ContinueStmt::Print(int indent) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ForeachStmt
|
||||
|
||||
ForeachStmt::ForeachStmt(const std::vector<Symbol *> &lvs,
|
||||
const std::vector<Expr *> &se,
|
||||
const std::vector<Expr *> &ee,
|
||||
ForeachStmt::ForeachStmt(const std::vector<Symbol *> &lvs,
|
||||
const std::vector<Expr *> &se,
|
||||
const std::vector<Expr *> &ee,
|
||||
Stmt *s, bool t, SourcePos pos)
|
||||
: Stmt(pos), dimVariables(lvs), startExprs(se), endExprs(ee), isTiled(t),
|
||||
stmts(s) {
|
||||
@@ -1266,16 +1266,16 @@ ForeachStmt::ForeachStmt(const std::vector<Symbol *> &lvs,
|
||||
values for use within the loop body.
|
||||
*/
|
||||
static llvm::Value *
|
||||
lUpdateVaryingCounter(int dim, int nDims, FunctionEmitContext *ctx,
|
||||
lUpdateVaryingCounter(int dim, int nDims, FunctionEmitContext *ctx,
|
||||
llvm::Value *uniformCounterPtr,
|
||||
llvm::Value *varyingCounterPtr,
|
||||
const std::vector<int> &spans) {
|
||||
// Smear the uniform counter value out to be varying
|
||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtr);
|
||||
llvm::Value *smearCounter =
|
||||
llvm::Value *smearCounter =
|
||||
llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
||||
for (int i = 0; i < g->target.vectorWidth; ++i)
|
||||
smearCounter =
|
||||
smearCounter =
|
||||
ctx->InsertInst(smearCounter, counter, i, "smear_counter");
|
||||
|
||||
// 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
|
||||
// result to memory and then return it directly as well.
|
||||
llvm::Value *varyingCounter =
|
||||
llvm::Value *varyingCounter =
|
||||
ctx->BinaryOperator(llvm::Instruction::Add, smearCounter,
|
||||
LLVMInt32Vector(delta), "iter_val");
|
||||
ctx->StoreInst(varyingCounter, varyingCounterPtr);
|
||||
@@ -1349,7 +1349,7 @@ lGetSpans(int dimsLeft, int nDims, int itemsLeft, bool isTiled, int *a) {
|
||||
// 16-wide.
|
||||
*a = 4;
|
||||
else
|
||||
// Otherwise give this dimension a span of two.
|
||||
// Otherwise give this dimension a span of two.
|
||||
*a = 2;
|
||||
|
||||
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
|
||||
ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (ctx->GetCurrentBasicBlock() == NULL || stmts == NULL)
|
||||
if (ctx->GetCurrentBasicBlock() == NULL || stmts == NULL)
|
||||
return;
|
||||
|
||||
llvm::BasicBlock *bbFullBody = ctx->CreateBasicBlock("foreach_full_body");
|
||||
@@ -1381,7 +1381,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
ctx->SetFunctionMask(LLVMMaskAllOn);
|
||||
|
||||
// This should be caught during typechecking
|
||||
AssertPos(pos, startExprs.size() == dimVariables.size() &&
|
||||
AssertPos(pos, startExprs.size() == dimVariables.size() &&
|
||||
endExprs.size() == dimVariables.size());
|
||||
int nDims = (int)dimVariables.size();
|
||||
|
||||
@@ -1413,7 +1413,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
endVals.push_back(ev);
|
||||
|
||||
// nItems = endVal - startVal
|
||||
llvm::Value *nItems =
|
||||
llvm::Value *nItems =
|
||||
ctx->BinaryOperator(llvm::Instruction::Sub, ev, sv, "nitems");
|
||||
|
||||
// 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
|
||||
// dimension. Its value is only used internally here for looping
|
||||
// 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"));
|
||||
ctx->StoreInst(startVals[i], uniformCounterPtrs[i]);
|
||||
|
||||
// There is also a varying variable that holds the set of index
|
||||
// values for each dimension in the current loop iteration; this is
|
||||
// the value that is program-visible.
|
||||
dimVariables[i]->storagePtr =
|
||||
ctx->AllocaInst(LLVMTypes::Int32VectorType,
|
||||
dimVariables[i]->storagePtr =
|
||||
ctx->AllocaInst(LLVMTypes::Int32VectorType,
|
||||
dimVariables[i]->name.c_str());
|
||||
dimVariables[i]->parentFunction = ctx->GetFunction();
|
||||
ctx->EmitVariableDebugInfo(dimVariables[i]);
|
||||
@@ -1482,7 +1482,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
for (int i = 0; i < nDims-1; ++i) {
|
||||
ctx->SetCurrentBasicBlock(bbStep[i]);
|
||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[i]);
|
||||
llvm::Value *newCounter =
|
||||
llvm::Value *newCounter =
|
||||
ctx->BinaryOperator(llvm::Instruction::Add, counter,
|
||||
LLVMInt32(span[i]), "new_counter");
|
||||
ctx->StoreInst(newCounter, uniformCounterPtrs[i]);
|
||||
@@ -1495,15 +1495,15 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
for (int i = 0; i < nDims-1; ++i) {
|
||||
ctx->SetCurrentBasicBlock(bbTest[i]);
|
||||
|
||||
llvm::Value *haveExtras =
|
||||
llvm::Value *haveExtras =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGT,
|
||||
endVals[i], alignedEnd[i], "have_extras");
|
||||
|
||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[i], "counter");
|
||||
llvm::Value *atAlignedEnd =
|
||||
llvm::Value *atAlignedEnd =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
|
||||
counter, alignedEnd[i], "at_aligned_end");
|
||||
llvm::Value *inEx =
|
||||
llvm::Value *inEx =
|
||||
ctx->BinaryOperator(llvm::Instruction::And, haveExtras,
|
||||
atAlignedEnd, "in_extras");
|
||||
|
||||
@@ -1513,8 +1513,8 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
inExtras.push_back(ctx->BinaryOperator(llvm::Instruction::Or, inEx,
|
||||
inExtras[i-1], "in_extras_all"));
|
||||
|
||||
llvm::Value *varyingCounter =
|
||||
lUpdateVaryingCounter(i, nDims, ctx, uniformCounterPtrs[i],
|
||||
llvm::Value *varyingCounter =
|
||||
lUpdateVaryingCounter(i, nDims, ctx, uniformCounterPtrs[i],
|
||||
dimVariables[i]->storagePtr, span);
|
||||
|
||||
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");
|
||||
// Do a vector compare of its value to the end value to generate a
|
||||
// mask for this last bit of work.
|
||||
llvm::Value *emask =
|
||||
llvm::Value *emask =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||
varyingCounter, smearEnd);
|
||||
emask = ctx->I1VecToBoolVec(emask);
|
||||
@@ -1537,7 +1537,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
ctx->StoreInst(newMask, extrasMaskPtrs[i]);
|
||||
}
|
||||
|
||||
llvm::Value *notAtEnd =
|
||||
llvm::Value *notAtEnd =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||
counter, endVals[i]);
|
||||
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
|
||||
// (i.e. processing extra elements that don't exactly fit into a
|
||||
// vector).
|
||||
llvm::BasicBlock *bbOuterInExtras =
|
||||
llvm::BasicBlock *bbOuterInExtras =
|
||||
ctx->CreateBasicBlock("outer_in_extras");
|
||||
llvm::BasicBlock *bbOuterNotInExtras =
|
||||
llvm::BasicBlock *bbOuterNotInExtras =
|
||||
ctx->CreateBasicBlock("outer_not_in_extras");
|
||||
|
||||
ctx->SetCurrentBasicBlock(bbTest[nDims-1]);
|
||||
@@ -1609,12 +1609,12 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
ctx->SetCurrentBasicBlock(bbOuterInExtras); {
|
||||
// Update the varying counter value here, since all subsequent
|
||||
// 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);
|
||||
|
||||
// here we just check to see if counter < alignedEnd
|
||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
|
||||
llvm::Value *beforeAlignedEnd =
|
||||
llvm::Value *beforeAlignedEnd =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||
counter, alignedEnd[nDims-1], "before_aligned_end");
|
||||
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
|
||||
// runs in multiple cases: both for handling any ragged extra data for
|
||||
// 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
|
||||
// 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
|
||||
// for the final bits here
|
||||
ctx->SetCurrentBasicBlock(bbPartial); {
|
||||
llvm::Value *varyingCounter =
|
||||
llvm::Value *varyingCounter =
|
||||
ctx->LoadInst(dimVariables[nDims-1]->storagePtr);
|
||||
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
||||
for (int j = 0; j < g->target.vectorWidth; ++j)
|
||||
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,
|
||||
varyingCounter, smearEnd);
|
||||
emask = ctx->I1VecToBoolVec(emask);
|
||||
@@ -1701,7 +1701,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
ctx->CreateBasicBlock("partial_inner_all_outer");
|
||||
ctx->SetCurrentBasicBlock(bbOuterNotInExtras); {
|
||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
|
||||
llvm::Value *beforeAlignedEnd =
|
||||
llvm::Value *beforeAlignedEnd =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||
counter, alignedEnd[nDims-1], "before_aligned_end");
|
||||
ctx->BranchInst(bbFullBody, bbPartialInnerAllOuter,
|
||||
@@ -1714,12 +1714,12 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
// on'. This ends up being relatively straightforward: just update the
|
||||
// value of the varying loop counter and have the statements in the
|
||||
// loop body emit their code.
|
||||
llvm::BasicBlock *bbFullBodyContinue =
|
||||
llvm::BasicBlock *bbFullBodyContinue =
|
||||
ctx->CreateBasicBlock("foreach_full_continue");
|
||||
ctx->SetCurrentBasicBlock(bbFullBody); {
|
||||
ctx->SetInternalMask(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);
|
||||
ctx->SetContinueTarget(bbFullBodyContinue);
|
||||
ctx->AddInstrumentationPoint("foreach loop body (all on)");
|
||||
@@ -1730,7 +1730,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
ctx->SetCurrentBasicBlock(bbFullBodyContinue); {
|
||||
ctx->RestoreContinuedLanes();
|
||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1]);
|
||||
llvm::Value *newCounter =
|
||||
llvm::Value *newCounter =
|
||||
ctx->BinaryOperator(llvm::Instruction::Add, counter,
|
||||
LLVMInt32(span[nDims-1]), "new_counter");
|
||||
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
|
||||
// less than the end value, in which case we need to run the body one
|
||||
// more time to get the extra bits.
|
||||
llvm::BasicBlock *bbSetInnerMask =
|
||||
llvm::BasicBlock *bbSetInnerMask =
|
||||
ctx->CreateBasicBlock("partial_inner_only");
|
||||
ctx->SetCurrentBasicBlock(bbPartialInnerAllOuter); {
|
||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
|
||||
llvm::Value *beforeFullEnd =
|
||||
llvm::Value *beforeFullEnd =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||
counter, endVals[nDims-1], "before_full_end");
|
||||
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
|
||||
// mask for the innermost dimension
|
||||
ctx->SetCurrentBasicBlock(bbSetInnerMask); {
|
||||
llvm::Value *varyingCounter =
|
||||
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
|
||||
llvm::Value *varyingCounter =
|
||||
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
|
||||
dimVariables[nDims-1]->storagePtr, span);
|
||||
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
||||
for (int j = 0; j < g->target.vectorWidth; ++j)
|
||||
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,
|
||||
varyingCounter, smearEnd);
|
||||
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
|
||||
// mask known to be all-on, which in turn leads to more efficient code
|
||||
// for that case.
|
||||
llvm::BasicBlock *bbStepInnerIndex =
|
||||
llvm::BasicBlock *bbStepInnerIndex =
|
||||
ctx->CreateBasicBlock("step_inner_index");
|
||||
llvm::BasicBlock *bbMaskedBodyContinue =
|
||||
llvm::BasicBlock *bbMaskedBodyContinue =
|
||||
ctx->CreateBasicBlock("foreach_masked_continue");
|
||||
ctx->SetCurrentBasicBlock(bbMaskedBody); {
|
||||
ctx->AddInstrumentationPoint("foreach loop body (masked)");
|
||||
@@ -1802,7 +1802,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
// innermost for loop over full vectors.
|
||||
ctx->SetCurrentBasicBlock(bbStepInnerIndex); {
|
||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1]);
|
||||
llvm::Value *newCounter =
|
||||
llvm::Value *newCounter =
|
||||
ctx->BinaryOperator(llvm::Instruction::Add, counter,
|
||||
LLVMInt32(span[nDims-1]), "new_counter");
|
||||
ctx->StoreInst(newCounter, uniformCounterPtrs[nDims-1]);
|
||||
@@ -1826,8 +1826,8 @@ ForeachStmt::TypeCheck() {
|
||||
bool anyErrors = false;
|
||||
for (unsigned int i = 0; i < startExprs.size(); ++i) {
|
||||
if (startExprs[i] != NULL)
|
||||
startExprs[i] = TypeConvertExpr(startExprs[i],
|
||||
AtomicType::UniformInt32,
|
||||
startExprs[i] = TypeConvertExpr(startExprs[i],
|
||||
AtomicType::UniformInt32,
|
||||
"foreach starting value");
|
||||
anyErrors |= (startExprs[i] == NULL);
|
||||
}
|
||||
@@ -1875,12 +1875,12 @@ ForeachStmt::Print(int indent) const {
|
||||
printf("%*cForeach Stmt", indent, ' ');
|
||||
pos.Print();
|
||||
printf("\n");
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < dimVariables.size(); ++i)
|
||||
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());
|
||||
else
|
||||
else
|
||||
printf("%*cVar %d: NULL\n", indent+4, ' ', i);
|
||||
|
||||
printf("Start values:\n");
|
||||
@@ -1917,7 +1917,7 @@ ForeachStmt::Print(int indent) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ForeachActiveStmt
|
||||
|
||||
ForeachActiveStmt::ForeachActiveStmt(Symbol *s, Stmt *st, SourcePos pos)
|
||||
ForeachActiveStmt::ForeachActiveStmt(Symbol *s, Stmt *st, SourcePos pos)
|
||||
: Stmt(pos) {
|
||||
sym = s;
|
||||
stmts = st;
|
||||
@@ -1926,7 +1926,7 @@ ForeachActiveStmt::ForeachActiveStmt(Symbol *s, Stmt *st, SourcePos pos)
|
||||
|
||||
void
|
||||
ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
// 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);
|
||||
return;
|
||||
}
|
||||
Assert(Type::Equal(sym->type,
|
||||
Assert(Type::Equal(sym->type,
|
||||
AtomicType::UniformInt64->GetAsConstType()));
|
||||
sym->storagePtr = ctx->AllocaInst(LLVMTypes::Int64Type, sym->name.c_str());
|
||||
|
||||
@@ -1944,22 +1944,22 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
ctx->EmitVariableDebugInfo(sym);
|
||||
|
||||
// The various basic blocks that we'll need in the below
|
||||
llvm::BasicBlock *bbFindNext =
|
||||
llvm::BasicBlock *bbFindNext =
|
||||
ctx->CreateBasicBlock("foreach_active_find_next");
|
||||
llvm::BasicBlock *bbBody = ctx->CreateBasicBlock("foreach_active_body");
|
||||
llvm::BasicBlock *bbCheckForMore =
|
||||
llvm::BasicBlock *bbCheckForMore =
|
||||
ctx->CreateBasicBlock("foreach_active_check_for_more");
|
||||
llvm::BasicBlock *bbDone = ctx->CreateBasicBlock("foreach_active_done");
|
||||
|
||||
// Save the old mask so that we can restore it at the end
|
||||
llvm::Value *oldInternalMask = ctx->GetInternalMask();
|
||||
|
||||
|
||||
// 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
|
||||
// the current execution mask (which should never be all off going in
|
||||
// to this)...
|
||||
llvm::Value *oldFullMask = ctx->GetFullMask();
|
||||
llvm::Value *maskBitsPtr =
|
||||
llvm::Value *maskBitsPtr =
|
||||
ctx->AllocaInst(LLVMTypes::Int64Type, "mask_bits");
|
||||
llvm::Value *movmsk = ctx->LaneMask(oldFullMask);
|
||||
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
|
||||
ctx->BranchInst(bbFindNext);
|
||||
|
||||
|
||||
ctx->SetCurrentBasicBlock(bbFindNext); {
|
||||
// Load the bitmask of the lanes left to be processed
|
||||
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
||||
|
||||
// Find the index of the first set bit in the mask
|
||||
llvm::Function *ctlzFunc =
|
||||
llvm::Function *ctlzFunc =
|
||||
m->module->getFunction("__count_trailing_zeros_i64");
|
||||
Assert(ctlzFunc != NULL);
|
||||
llvm::Value *firstSet = ctx->CallInst(ctlzFunc, NULL, remainingBits,
|
||||
@@ -1993,20 +1993,20 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
// math...)
|
||||
|
||||
// Get the "program index" vector value
|
||||
llvm::Value *programIndex =
|
||||
llvm::Value *programIndex =
|
||||
llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
||||
for (int i = 0; i < g->target.vectorWidth; ++i)
|
||||
programIndex = ctx->InsertInst(programIndex, LLVMInt32(i), i,
|
||||
"prog_index");
|
||||
|
||||
// And smear the current lane out to a vector
|
||||
llvm::Value *firstSet32 =
|
||||
llvm::Value *firstSet32 =
|
||||
ctx->TruncInst(firstSet, LLVMTypes::Int32Type, "first_set32");
|
||||
llvm::Value *firstSet32Smear = ctx->SmearUniform(firstSet32);
|
||||
|
||||
// Now set the execution mask based on doing a vector compare of
|
||||
// these two
|
||||
llvm::Value *iterMask =
|
||||
llvm::Value *iterMask =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
|
||||
firstSet32Smear, programIndex);
|
||||
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
|
||||
// the lane we're about to run.
|
||||
llvm::Value *setMask =
|
||||
llvm::Value *setMask =
|
||||
ctx->BinaryOperator(llvm::Instruction::Shl, LLVMInt64(1),
|
||||
firstSet, "set_mask");
|
||||
llvm::Value *notSetMask = ctx->NotOperator(setMask);
|
||||
llvm::Value *newRemaining =
|
||||
ctx->BinaryOperator(llvm::Instruction::And, remainingBits,
|
||||
llvm::Value *newRemaining =
|
||||
ctx->BinaryOperator(llvm::Instruction::And, remainingBits,
|
||||
notSetMask, "new_remaining");
|
||||
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
|
||||
// to be processed.
|
||||
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
||||
llvm::Value *nonZero =
|
||||
llvm::Value *nonZero =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
|
||||
remainingBits, LLVMInt64(0), "remaining_ne_zero");
|
||||
ctx->BranchInst(bbFindNext, bbDone, nonZero);
|
||||
@@ -2102,8 +2102,8 @@ ForeachActiveStmt::EstimateCost() const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ForeachUniqueStmt
|
||||
|
||||
ForeachUniqueStmt::ForeachUniqueStmt(const char *iterName, Expr *e,
|
||||
Stmt *s, SourcePos pos)
|
||||
ForeachUniqueStmt::ForeachUniqueStmt(const char *iterName, Expr *e,
|
||||
Stmt *s, SourcePos pos)
|
||||
: Stmt(pos) {
|
||||
sym = m->symbolTable->LookupVariable(iterName);
|
||||
expr = e;
|
||||
@@ -2113,7 +2113,7 @@ ForeachUniqueStmt::ForeachUniqueStmt(const char *iterName, Expr *e,
|
||||
|
||||
void
|
||||
ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
// 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;
|
||||
if (exprValue == NULL ||
|
||||
(exprType = expr->GetType()) == NULL ||
|
||||
(llvmExprType =
|
||||
(llvmExprType =
|
||||
llvm::dyn_cast<llvm::VectorType>(exprValue->getType())) == NULL) {
|
||||
Assert(m->errorCount > 0);
|
||||
return;
|
||||
@@ -2179,13 +2179,13 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
|
||||
// Onward to find the first set of lanes to run the loop for
|
||||
ctx->BranchInst(bbFindNext);
|
||||
|
||||
|
||||
ctx->SetCurrentBasicBlock(bbFindNext); {
|
||||
// Load the bitmask of the lanes left to be processed
|
||||
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
||||
|
||||
// Find the index of the first set bit in the mask
|
||||
llvm::Function *ctlzFunc =
|
||||
llvm::Function *ctlzFunc =
|
||||
m->module->getFunction("__count_trailing_zeros_i64");
|
||||
Assert(ctlzFunc != NULL);
|
||||
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
|
||||
// memory storing the value of the varying expr.
|
||||
llvm::Value *uniqueValuePtr =
|
||||
llvm::Value *uniqueValuePtr =
|
||||
ctx->GetElementPtrInst(exprMem, LLVMInt64(0), firstSet, exprPtrType,
|
||||
"unique_index_ptr");
|
||||
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 *matchingLanes = NULL;
|
||||
if (uniqueValue->getType()->isFloatingPointTy())
|
||||
matchingLanes =
|
||||
matchingLanes =
|
||||
ctx->CmpInst(llvm::Instruction::FCmp, llvm::CmpInst::FCMP_OEQ,
|
||||
uniqueSmear, exprValue, "matching_lanes");
|
||||
else
|
||||
matchingLanes =
|
||||
matchingLanes =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
|
||||
uniqueSmear, exprValue, "matching_lanes");
|
||||
matchingLanes = ctx->I1VecToBoolVec(matchingLanes);
|
||||
|
||||
llvm::Value *loopMask =
|
||||
llvm::Value *loopMask =
|
||||
ctx->BinaryOperator(llvm::Instruction::And, oldMask, matchingLanes,
|
||||
"foreach_unique_loop_mask");
|
||||
ctx->SetInternalMask(loopMask);
|
||||
@@ -2234,8 +2234,8 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
// remainingBits &= ~movmsk(current mask)
|
||||
llvm::Value *loopMaskMM = ctx->LaneMask(loopMask);
|
||||
llvm::Value *notLoopMaskMM = ctx->NotOperator(loopMaskMM);
|
||||
llvm::Value *newRemaining =
|
||||
ctx->BinaryOperator(llvm::Instruction::And, remainingBits,
|
||||
llvm::Value *newRemaining =
|
||||
ctx->BinaryOperator(llvm::Instruction::And, remainingBits,
|
||||
notLoopMaskMM, "new_remaining");
|
||||
ctx->StoreInst(newRemaining, maskBitsPtr);
|
||||
|
||||
@@ -2260,7 +2260,7 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
// to be processed.
|
||||
ctx->RestoreContinuedLanes();
|
||||
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
||||
llvm::Value *nonZero =
|
||||
llvm::Value *nonZero =
|
||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
|
||||
remainingBits, LLVMInt64(0), "remaining_ne_zero");
|
||||
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) {
|
||||
stmts = s;
|
||||
}
|
||||
@@ -2397,7 +2397,7 @@ CaseStmt::EstimateCost() const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// DefaultStmt
|
||||
|
||||
DefaultStmt::DefaultStmt(Stmt *s, SourcePos pos)
|
||||
DefaultStmt::DefaultStmt(Stmt *s, SourcePos pos)
|
||||
: Stmt(pos) {
|
||||
stmts = s;
|
||||
}
|
||||
@@ -2435,7 +2435,7 @@ DefaultStmt::EstimateCost() const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// SwitchStmt
|
||||
|
||||
SwitchStmt::SwitchStmt(Expr *e, Stmt *s, SourcePos pos)
|
||||
SwitchStmt::SwitchStmt(Expr *e, Stmt *s, SourcePos pos)
|
||||
: Stmt(pos) {
|
||||
expr = e;
|
||||
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
|
||||
"switch". */
|
||||
struct SwitchVisitInfo {
|
||||
SwitchVisitInfo(FunctionEmitContext *c) {
|
||||
SwitchVisitInfo(FunctionEmitContext *c) {
|
||||
ctx = c;
|
||||
defaultBlock = NULL;
|
||||
defaultBlock = NULL;
|
||||
lastBlock = NULL;
|
||||
}
|
||||
|
||||
@@ -2491,11 +2491,11 @@ lSwitchASTPreVisit(ASTNode *node, void *d) {
|
||||
// already
|
||||
for (int i = 0; i < (int)svi->caseBlocks.size(); ++i) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Otherwise create a new basic block for the code following this
|
||||
// 'case' statement and record the mappign between the case label
|
||||
// value and the basic block
|
||||
@@ -2689,14 +2689,14 @@ UnmaskedStmt::EstimateCost() const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ReturnStmt
|
||||
|
||||
ReturnStmt::ReturnStmt(Expr *e, SourcePos p)
|
||||
ReturnStmt::ReturnStmt(Expr *e, SourcePos p)
|
||||
: Stmt(p), expr(e) {
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ReturnStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
if (ctx->InForeachLoop()) {
|
||||
@@ -2756,7 +2756,7 @@ ReturnStmt::Print(int indent) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// GotoStmt
|
||||
|
||||
GotoStmt::GotoStmt(const char *l, SourcePos gotoPos, SourcePos ip)
|
||||
GotoStmt::GotoStmt(const char *l, SourcePos gotoPos, SourcePos ip)
|
||||
: Stmt(gotoPos) {
|
||||
label = l;
|
||||
identifierPos = ip;
|
||||
@@ -2765,7 +2765,7 @@ GotoStmt::GotoStmt(const char *l, SourcePos gotoPos, SourcePos ip)
|
||||
|
||||
void
|
||||
GotoStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
if (ctx->VaryingCFDepth() > 0) {
|
||||
@@ -2793,7 +2793,7 @@ GotoStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
/* Label wasn't found. Emit an error */
|
||||
Error(identifierPos,
|
||||
Error(identifierPos,
|
||||
"No label named \"%s\" found in current function.%s",
|
||||
label.c_str(), match_output.c_str());
|
||||
|
||||
@@ -2832,7 +2832,7 @@ GotoStmt::EstimateCost() const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// LabeledStmt
|
||||
|
||||
LabeledStmt::LabeledStmt(const char *n, Stmt *s, SourcePos p)
|
||||
LabeledStmt::LabeledStmt(const char *n, Stmt *s, SourcePos p)
|
||||
: Stmt(p) {
|
||||
name = n;
|
||||
stmt = s;
|
||||
@@ -2934,7 +2934,7 @@ StmtList::Print(int indent) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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) {
|
||||
}
|
||||
|
||||
@@ -2995,11 +2995,11 @@ lProcessPrintArg(Expr *expr, FunctionEmitContext *ctx, std::string &argTypes) {
|
||||
Type::Equal(baseType, AtomicType::UniformInt16) ||
|
||||
Type::Equal(baseType, AtomicType::UniformUInt16)) {
|
||||
expr = new TypeCastExpr(type->IsUniformType() ? AtomicType::UniformInt32 :
|
||||
AtomicType::VaryingInt32,
|
||||
AtomicType::VaryingInt32,
|
||||
expr, expr->pos);
|
||||
type = expr->GetType();
|
||||
}
|
||||
|
||||
|
||||
char t = lEncodeType(type->GetAsNonConstType());
|
||||
if (t == '\0') {
|
||||
Error(expr->pos, "Only atomic types are allowed in print statements; "
|
||||
@@ -3030,7 +3030,7 @@ lProcessPrintArg(Expr *expr, FunctionEmitContext *ctx, std::string &argTypes) {
|
||||
*/
|
||||
void
|
||||
PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
ctx->SetDebugPos(pos);
|
||||
@@ -3039,7 +3039,7 @@ PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
// in the code emitted below
|
||||
//
|
||||
// 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
|
||||
// 3. the number of running program instances (i.e. the target's
|
||||
// vector width)
|
||||
@@ -3049,7 +3049,7 @@ PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
std::string argTypes;
|
||||
|
||||
if (values == NULL) {
|
||||
llvm::Type *ptrPtrType =
|
||||
llvm::Type *ptrPtrType =
|
||||
llvm::PointerType::get(LLVMTypes::VoidPointerType, 0);
|
||||
args[4] = llvm::Constant::getNullValue(ptrPtrType);
|
||||
}
|
||||
@@ -3060,14 +3060,14 @@ PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
ExprList *elist = dynamic_cast<ExprList *>(values);
|
||||
int nArgs = elist ? elist->exprs.size() : 1;
|
||||
|
||||
// Allocate space for the array of pointers to values to be printed
|
||||
llvm::Type *argPtrArrayType =
|
||||
// Allocate space for the array of pointers to values to be printed
|
||||
llvm::Type *argPtrArrayType =
|
||||
llvm::ArrayType::get(LLVMTypes::VoidPointerType, nArgs);
|
||||
llvm::Value *argPtrArray = ctx->AllocaInst(argPtrArrayType,
|
||||
"print_arg_ptrs");
|
||||
// Store the array pointer as a void **, which is what __do_print()
|
||||
// expects
|
||||
args[4] = ctx->BitCastInst(argPtrArray,
|
||||
args[4] = ctx->BitCastInst(argPtrArray,
|
||||
llvm::PointerType::get(LLVMTypes::VoidPointerType, 0));
|
||||
|
||||
// Now, for each of the arguments, emit code to evaluate its value
|
||||
@@ -3131,14 +3131,14 @@ PrintStmt::EstimateCost() const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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) {
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AssertStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
const Type *type;
|
||||
@@ -3151,14 +3151,14 @@ AssertStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
|
||||
// The actual functionality to do the check and then handle falure is
|
||||
// done via a builtin written in bitcode in builtins/util.m4.
|
||||
llvm::Function *assertFunc =
|
||||
llvm::Function *assertFunc =
|
||||
isUniform ? m->module->getFunction("__do_assert_uniform") :
|
||||
m->module->getFunction("__do_assert_varying");
|
||||
AssertPos(pos, assertFunc != NULL);
|
||||
|
||||
char *errorString;
|
||||
if (asprintf(&errorString, "%s:%d:%d: Assertion failed: %s",
|
||||
pos.name, pos.first_line, pos.first_column,
|
||||
if (asprintf(&errorString, "%s:%d:%d: Assertion failed: %s",
|
||||
pos.name, pos.first_line, pos.first_column,
|
||||
message.c_str()) == -1) {
|
||||
Error(pos, "Fatal error when generating assert string: asprintf() "
|
||||
"unable to allocate memory!");
|
||||
@@ -3191,8 +3191,8 @@ AssertStmt::TypeCheck() {
|
||||
const Type *type;
|
||||
if (expr && (type = expr->GetType()) != NULL) {
|
||||
bool isUniform = type->IsUniformType();
|
||||
expr = TypeConvertExpr(expr, isUniform ? AtomicType::UniformBool :
|
||||
AtomicType::VaryingBool,
|
||||
expr = TypeConvertExpr(expr, isUniform ? AtomicType::UniformBool :
|
||||
AtomicType::VaryingBool,
|
||||
"\"assert\" statement");
|
||||
if (expr == NULL)
|
||||
return NULL;
|
||||
@@ -3218,7 +3218,7 @@ DeleteStmt::DeleteStmt(Expr *e, SourcePos p)
|
||||
|
||||
void
|
||||
DeleteStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
if (!ctx->GetCurrentBasicBlock())
|
||||
return;
|
||||
|
||||
const Type *exprType;
|
||||
|
||||
22
stmt.h
22
stmt.h
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -84,8 +84,8 @@ public:
|
||||
|
||||
|
||||
struct VariableDeclaration {
|
||||
VariableDeclaration(Symbol *s = NULL, Expr *i = NULL) {
|
||||
sym = s; init = i;
|
||||
VariableDeclaration(Symbol *s = NULL, Expr *i = NULL) {
|
||||
sym = s; init = i;
|
||||
}
|
||||
Symbol *sym;
|
||||
Expr *init;
|
||||
@@ -137,12 +137,12 @@ private:
|
||||
'false' blocks. */
|
||||
const bool doAllCheck;
|
||||
|
||||
void emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||
void emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||
llvm::Value *test) const;
|
||||
void emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *test) const;
|
||||
void emitMaskAllOn(FunctionEmitContext *ctx,
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -152,7 +152,7 @@ private:
|
||||
*/
|
||||
class DoStmt : public Stmt {
|
||||
public:
|
||||
DoStmt(Expr *testExpr, Stmt *bodyStmts, bool doCoherentCheck,
|
||||
DoStmt(Expr *testExpr, Stmt *bodyStmts, bool doCoherentCheck,
|
||||
SourcePos pos);
|
||||
|
||||
void EmitCode(FunctionEmitContext *ctx) const;
|
||||
@@ -227,9 +227,9 @@ public:
|
||||
*/
|
||||
class ForeachStmt : public Stmt {
|
||||
public:
|
||||
ForeachStmt(const std::vector<Symbol *> &loopVars,
|
||||
const std::vector<Expr *> &startExprs,
|
||||
const std::vector<Expr *> &endExprs,
|
||||
ForeachStmt(const std::vector<Symbol *> &loopVars,
|
||||
const std::vector<Expr *> &startExprs,
|
||||
const std::vector<Expr *> &endExprs,
|
||||
Stmt *bodyStatements, bool tiled, SourcePos pos);
|
||||
|
||||
void EmitCode(FunctionEmitContext *ctx) const;
|
||||
@@ -283,7 +283,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
*/
|
||||
class UnmaskedStmt : public Stmt {
|
||||
public:
|
||||
@@ -493,7 +493,7 @@ public:
|
||||
Expr *expr;
|
||||
};
|
||||
|
||||
extern Stmt *CreateForeachActiveStmt(Symbol *iterSym, Stmt *stmts,
|
||||
extern Stmt *CreateForeachActiveStmt(Symbol *iterSym, Stmt *stmts,
|
||||
SourcePos pos);
|
||||
|
||||
#endif // ISPC_STMT_H
|
||||
|
||||
18
sym.cpp
18
sym.cpp
@@ -28,11 +28,11 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@brief file with definitions for symbol and symbol table classes.
|
||||
@brief file with definitions for symbol and symbol table classes.
|
||||
*/
|
||||
|
||||
#include "sym.h"
|
||||
@@ -43,8 +43,8 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Symbol
|
||||
|
||||
Symbol::Symbol(const std::string &n, SourcePos p, const Type *t,
|
||||
StorageClass sc)
|
||||
Symbol::Symbol(const std::string &n, SourcePos p, const Type *t,
|
||||
StorageClass sc)
|
||||
: pos(p), name(n) {
|
||||
storagePtr = NULL;
|
||||
function = exportedFunction = NULL;
|
||||
@@ -72,7 +72,7 @@ SymbolTable::~SymbolTable() {
|
||||
|
||||
|
||||
void
|
||||
SymbolTable::PushScope() {
|
||||
SymbolTable::PushScope() {
|
||||
SymbolMapType *sm;
|
||||
if (freeSymbolMaps.size() > 0) {
|
||||
sm = freeSymbolMaps.back();
|
||||
@@ -87,7 +87,7 @@ SymbolTable::PushScope() {
|
||||
|
||||
|
||||
void
|
||||
SymbolTable::PopScope() {
|
||||
SymbolTable::PopScope() {
|
||||
Assert(variables.size() > 1);
|
||||
freeSymbolMaps.push_back(variables.back());
|
||||
variables.pop_back();
|
||||
@@ -105,14 +105,14 @@ SymbolTable::AddVariable(Symbol *symbol) {
|
||||
if (i == (int)variables.size()-1) {
|
||||
// If a symbol of the same name was declared in the
|
||||
// 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());
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// Otherwise it's just shadowing something else, which
|
||||
// is legal but dangerous..
|
||||
Warning(symbol->pos,
|
||||
Warning(symbol->pos,
|
||||
"Symbol \"%s\" shadows symbol declared in outer scope.",
|
||||
symbol->name.c_str());
|
||||
(*variables.back())[symbol->name] = symbol;
|
||||
@@ -308,7 +308,7 @@ SymbolTable::Print() {
|
||||
for (iter = sm.begin(); iter != sm.end(); ++iter) {
|
||||
fprintf(stderr, "%*c", depth, ' ');
|
||||
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());
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
48
sym.h
48
sym.h
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
location in memory.) */
|
||||
llvm::Function *function; /*!< For symbols that represent functions,
|
||||
this stores the LLVM Function value for
|
||||
the symbol once it has been created. */
|
||||
the symbol once it has been created. */
|
||||
llvm::Function *exportedFunction;
|
||||
/*!< For symbols that represent functions with
|
||||
'export' qualifiers, this points to the LLVM
|
||||
@@ -91,18 +91,18 @@ public:
|
||||
struct types. For cases like these, ConstExpr is NULL,
|
||||
though for all const symbols, the value pointed to by the
|
||||
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). */
|
||||
StorageClass storageClass;/*!< Records the storage class (if any) provided with the
|
||||
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
|
||||
this value available makes it possible to avoid performing
|
||||
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. */
|
||||
const Function *parentFunction;
|
||||
/*!< For symbols that are parameters to functions or are
|
||||
const Function *parentFunction;
|
||||
/*!< For symbols that are parameters to functions or are
|
||||
variables declared inside functions, this gives the
|
||||
function they're in. */
|
||||
};
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
|
||||
/** For each scope started by a call to SymbolTable::PushScope(), there
|
||||
must be a matching call to SymbolTable::PopScope() at the end of
|
||||
that scope. */
|
||||
that scope. */
|
||||
void PopScope();
|
||||
|
||||
/** Adds the given variable symbol to the symbol table.
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
returning the first match found.
|
||||
|
||||
@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 *LookupVariable(const char *name);
|
||||
|
||||
@@ -165,7 +165,7 @@ public:
|
||||
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
|
||||
were found. */
|
||||
bool LookupFunction(const char *name,
|
||||
bool LookupFunction(const char *name,
|
||||
std::vector<Symbol *> *matches = NULL);
|
||||
|
||||
/** 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. */
|
||||
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.
|
||||
|
||||
@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
|
||||
set of matches. It can either be a function, with signature
|
||||
<tt>bool pred(const Symbol *s)</tt>, or a unary predicate object with
|
||||
@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
|
||||
set of matches. It can either be a function, with signature
|
||||
<tt>bool pred(const Symbol *s)</tt>, or a unary predicate object with
|
||||
an <tt>bool operator()(const Symbol *)</tt> method.
|
||||
|
||||
@param matches Pointer to a vector in which to return the matching
|
||||
symbols.
|
||||
symbols.
|
||||
*/
|
||||
template <typename Predicate>
|
||||
void GetMatchingFunctions(Predicate pred,
|
||||
template <typename Predicate>
|
||||
void GetMatchingFunctions(Predicate pred,
|
||||
std::vector<Symbol *> *matches) const;
|
||||
|
||||
/** Returns all of the variable symbols in the symbol table that match
|
||||
the given predicate. The predicate is defined as in the
|
||||
GetMatchingFunctions() method.
|
||||
*/
|
||||
template <typename Predicate>
|
||||
void GetMatchingVariables(Predicate pred,
|
||||
template <typename Predicate>
|
||||
void GetMatchingVariables(Predicate pred,
|
||||
std::vector<Symbol *> *matches) const;
|
||||
|
||||
/** 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
|
||||
@return true if the named type was successfully added. False if a type
|
||||
with the same name has already been defined.
|
||||
|
||||
|
||||
*/
|
||||
bool AddType(const char *name, const Type *type, SourcePos pos);
|
||||
|
||||
@@ -248,7 +248,7 @@ public:
|
||||
const Type *RandomType();
|
||||
|
||||
private:
|
||||
std::vector<std::string> closestTypeMatch(const char *str,
|
||||
std::vector<std::string> closestTypeMatch(const char *str,
|
||||
bool structsVsEnums) const;
|
||||
|
||||
/** This member variable holds one SymbolMap for each of the current
|
||||
@@ -278,7 +278,7 @@ private:
|
||||
|
||||
|
||||
template <typename Predicate> void
|
||||
SymbolTable::GetMatchingFunctions(Predicate pred,
|
||||
SymbolTable::GetMatchingFunctions(Predicate pred,
|
||||
std::vector<Symbol *> *matches) const {
|
||||
// Iterate through all function symbols and apply the given predicate.
|
||||
// If it returns true, add the Symbol * to the provided vector.
|
||||
@@ -294,7 +294,7 @@ SymbolTable::GetMatchingFunctions(Predicate pred,
|
||||
|
||||
|
||||
template <typename Predicate> void
|
||||
SymbolTable::GetMatchingVariables(Predicate pred,
|
||||
SymbolTable::GetMatchingVariables(Predicate pred,
|
||||
std::vector<Symbol *> *matches) const {
|
||||
for (unsigned int i = 0; i < variables.size(); ++i) {
|
||||
SymbolMapType &sm = *(variables[i]);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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)
|
||||
@@ -61,7 +61,7 @@ extern "C" {
|
||||
extern void f_duf(float *result, double *a, float b);
|
||||
extern void f_di(float *result, double *a, int *b);
|
||||
extern void result(float *val);
|
||||
|
||||
|
||||
void ISPCLaunch(void **handlePtr, void *f, void *d, int);
|
||||
void ISPCSync(void *handle);
|
||||
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);
|
||||
#else
|
||||
#error "Unknown or unset TEST_SIG value"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float expected_result[64];
|
||||
memset(expected_result, 0, 64*sizeof(float));
|
||||
@@ -155,7 +155,7 @@ int main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
#else
|
||||
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]);
|
||||
++errors;
|
||||
#endif // EXPECT_FAILURE
|
||||
|
||||
238
type.cpp
238
type.cpp
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -79,7 +79,7 @@ lShouldPrintName(const std::string &name) {
|
||||
|
||||
/** Utility routine to create a llvm DIArray type of the given number of
|
||||
the given element type. */
|
||||
static llvm::DIType
|
||||
static llvm::DIType
|
||||
lCreateDIArray(llvm::DIType eltType, int count) {
|
||||
int lowerBound = 0, upperBound = count-1;
|
||||
|
||||
@@ -125,9 +125,9 @@ Variability::GetString() const {
|
||||
std::string
|
||||
Variability::MangleString() const {
|
||||
switch (type) {
|
||||
case Uniform:
|
||||
case Uniform:
|
||||
return "un";
|
||||
case Varying:
|
||||
case Varying:
|
||||
return "vy";
|
||||
case SOA: {
|
||||
char buf[32];
|
||||
@@ -189,11 +189,11 @@ const AtomicType *AtomicType::UniformDouble =
|
||||
new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Uniform, false);
|
||||
const AtomicType *AtomicType::VaryingDouble =
|
||||
new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Varying, false);
|
||||
const AtomicType *AtomicType::Void =
|
||||
const AtomicType *AtomicType::Void =
|
||||
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) {
|
||||
asOtherConstType = NULL;
|
||||
asUniformType = asVaryingType = NULL;
|
||||
@@ -255,14 +255,14 @@ AtomicType::IsBoolType() const {
|
||||
|
||||
|
||||
bool
|
||||
AtomicType::IsConstType() const {
|
||||
return isConst;
|
||||
AtomicType::IsConstType() const {
|
||||
return isConst;
|
||||
}
|
||||
|
||||
|
||||
const AtomicType *
|
||||
AtomicType::GetAsUnsignedType() const {
|
||||
if (IsUnsignedType() == true)
|
||||
if (IsUnsignedType() == true)
|
||||
return this;
|
||||
|
||||
if (IsIntType() == false)
|
||||
@@ -286,9 +286,9 @@ AtomicType::GetAsUnsignedType() const {
|
||||
|
||||
const AtomicType *
|
||||
AtomicType::GetAsConstType() const {
|
||||
if (basicType == TYPE_VOID || isConst == true)
|
||||
if (basicType == TYPE_VOID || isConst == true)
|
||||
return this;
|
||||
|
||||
|
||||
if (asOtherConstType == NULL) {
|
||||
asOtherConstType = new AtomicType(basicType, variability, true);
|
||||
asOtherConstType->asOtherConstType = this;
|
||||
@@ -299,7 +299,7 @@ AtomicType::GetAsConstType() const {
|
||||
|
||||
const AtomicType *
|
||||
AtomicType::GetAsNonConstType() const {
|
||||
if (basicType == TYPE_VOID || isConst == false)
|
||||
if (basicType == TYPE_VOID || isConst == false)
|
||||
return this;
|
||||
|
||||
if (asOtherConstType == NULL) {
|
||||
@@ -429,7 +429,7 @@ AtomicType::Mangle() const {
|
||||
std::string
|
||||
AtomicType::GetCDeclaration(const std::string &name) const {
|
||||
std::string ret;
|
||||
if (variability != Variability::Uniform &&
|
||||
if (variability != Variability::Uniform &&
|
||||
variability != Variability::SOA) {
|
||||
Assert(m->errorCount > 0);
|
||||
return ret;
|
||||
@@ -583,7 +583,7 @@ AtomicType::GetDIType(llvm::DIDescriptor scope) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// EnumType
|
||||
|
||||
EnumType::EnumType(SourcePos p)
|
||||
EnumType::EnumType(SourcePos p)
|
||||
: Type(ENUM_TYPE), pos(p) {
|
||||
// name = "/* (anonymous) */";
|
||||
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) {
|
||||
isConst = false;
|
||||
variability = Variability(Variability::Unbound);
|
||||
@@ -604,31 +604,31 @@ EnumType::GetVariability() const {
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
bool
|
||||
EnumType::IsBoolType() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
bool
|
||||
EnumType::IsFloatType() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
bool
|
||||
EnumType::IsIntType() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
bool
|
||||
EnumType::IsUnsignedType() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
bool
|
||||
EnumType::IsConstType() const {
|
||||
return isConst;
|
||||
}
|
||||
@@ -724,7 +724,7 @@ EnumType::GetAsNonConstType() const {
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
std::string
|
||||
EnumType::GetString() const {
|
||||
std::string ret;
|
||||
if (isConst) ret += "const ";
|
||||
@@ -737,7 +737,7 @@ EnumType::GetString() const {
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
std::string
|
||||
EnumType::Mangle() const {
|
||||
Assert(variability != Variability::Unbound);
|
||||
|
||||
@@ -749,7 +749,7 @@ EnumType::Mangle() const {
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
std::string
|
||||
EnumType::GetCDeclaration(const std::string &varName) const {
|
||||
if (variability != Variability::Uniform &&
|
||||
variability != Variability::SOA) {
|
||||
@@ -798,7 +798,7 @@ EnumType::LLVMType(llvm::LLVMContext *ctx) const {
|
||||
}
|
||||
|
||||
|
||||
llvm::DIType
|
||||
llvm::DIType
|
||||
EnumType::GetDIType(llvm::DIDescriptor scope) const {
|
||||
std::vector<llvm::Value *> enumeratorDescriptors;
|
||||
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);
|
||||
Assert(count == 1);
|
||||
|
||||
llvm::Value *descriptor =
|
||||
llvm::Value *descriptor =
|
||||
m->diBuilder->createEnumerator(enumerators[i]->name, enumeratorValue);
|
||||
enumeratorDescriptors.push_back(descriptor);
|
||||
}
|
||||
llvm::DIArray elementArray =
|
||||
llvm::DIArray elementArray =
|
||||
m->diBuilder->getOrCreateArray(enumeratorDescriptors);
|
||||
|
||||
llvm::DIFile diFile = pos.GetDIFile();
|
||||
@@ -867,11 +867,11 @@ EnumType::GetEnumerator(int i) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// PointerType
|
||||
|
||||
PointerType *PointerType::Void =
|
||||
PointerType *PointerType::Void =
|
||||
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)
|
||||
: Type(POINTER_TYPE), variability(v), isConst(ic), isSlice(is), isFrozen(fr) {
|
||||
baseType = t;
|
||||
@@ -1013,7 +1013,7 @@ PointerType::ResolveUnboundVariability(Variability v) const {
|
||||
Assert(v != Variability::Unbound);
|
||||
Variability ptrVariability = (variability == Variability::Unbound) ? v :
|
||||
variability;
|
||||
const Type *resolvedBaseType =
|
||||
const Type *resolvedBaseType =
|
||||
baseType->ResolveUnboundVariability(Variability::Uniform);
|
||||
return new PointerType(resolvedBaseType, ptrVariability, isConst, isSlice,
|
||||
isFrozen);
|
||||
@@ -1038,7 +1038,7 @@ PointerType::GetAsNonConstType() const {
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
std::string
|
||||
PointerType::GetString() const {
|
||||
if (baseType == NULL) {
|
||||
Assert(m->errorCount > 0);
|
||||
@@ -1114,7 +1114,7 @@ PointerType::LLVMType(llvm::LLVMContext *ctx) const {
|
||||
if (isSlice) {
|
||||
llvm::Type *types[2];
|
||||
types[0] = GetAsNonSlice()->LLVMType(ctx);
|
||||
|
||||
|
||||
switch (variability.type) {
|
||||
case Variability::Uniform:
|
||||
types[1] = LLVMTypes::Int32Type;
|
||||
@@ -1140,7 +1140,7 @@ PointerType::LLVMType(llvm::LLVMContext *ctx) const {
|
||||
case Variability::Uniform: {
|
||||
llvm::Type *ptype = NULL;
|
||||
const FunctionType *ftype = CastType<FunctionType>(baseType);
|
||||
if (ftype != NULL)
|
||||
if (ftype != NULL)
|
||||
ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx), 0);
|
||||
else {
|
||||
if (baseType == AtomicType::Void)
|
||||
@@ -1177,11 +1177,11 @@ PointerType::GetDIType(llvm::DIDescriptor scope) const {
|
||||
int ptrAlignBits = bitsSize;
|
||||
switch (variability.type) {
|
||||
case Variability::Uniform:
|
||||
return m->diBuilder->createPointerType(diTargetType, bitsSize,
|
||||
return m->diBuilder->createPointerType(diTargetType, bitsSize,
|
||||
ptrAlignBits);
|
||||
case Variability::Varying: {
|
||||
// emit them as an array of pointers
|
||||
llvm::DIType eltType = m->diBuilder->createPointerType(diTargetType,
|
||||
llvm::DIType eltType = m->diBuilder->createPointerType(diTargetType,
|
||||
bitsSize, ptrAlignBits);
|
||||
return lCreateDIArray(eltType, g->target.vectorWidth);
|
||||
}
|
||||
@@ -1207,7 +1207,7 @@ const Type *SequentialType::GetElementType(int index) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ArrayType
|
||||
|
||||
ArrayType::ArrayType(const Type *c, int a)
|
||||
ArrayType::ArrayType(const Type *c, int a)
|
||||
: SequentialType(ARRAY_TYPE), child(c), numElements(a) {
|
||||
// 0 -> unsized array.
|
||||
Assert(numElements >= 0);
|
||||
@@ -1239,25 +1239,25 @@ ArrayType::GetVariability() const {
|
||||
|
||||
bool
|
||||
ArrayType::IsFloatType() const {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ArrayType::IsIntType() const {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ArrayType::IsUnsignedType() const {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
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]);
|
||||
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 "
|
||||
"make it impossible to size unsized array dimensions.");
|
||||
return NULL;
|
||||
@@ -1537,7 +1537,7 @@ ArrayType::SizeUnsizedArrays(const Type *type, Expr *initExpr) {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// VectorType
|
||||
|
||||
VectorType::VectorType(const AtomicType *b, int a)
|
||||
VectorType::VectorType(const AtomicType *b, int a)
|
||||
: SequentialType(VECTOR_TYPE), base(b), numElements(a) {
|
||||
Assert(numElements > 0);
|
||||
Assert(base != NULL);
|
||||
@@ -1546,37 +1546,37 @@ VectorType::VectorType(const AtomicType *b, int a)
|
||||
|
||||
Variability
|
||||
VectorType::GetVariability() const {
|
||||
return base->GetVariability();
|
||||
return base->GetVariability();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VectorType::IsFloatType() const {
|
||||
return base->IsFloatType();
|
||||
return base->IsFloatType();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VectorType::IsIntType() const {
|
||||
return base->IsIntType();
|
||||
return base->IsIntType();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VectorType::IsUnsignedType() const {
|
||||
return base->IsUnsignedType();
|
||||
return base->IsUnsignedType();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VectorType::IsBoolType() const {
|
||||
return base->IsBoolType();
|
||||
return base->IsBoolType();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VectorType::IsConstType() const {
|
||||
return base->IsConstType();
|
||||
return base->IsConstType();
|
||||
}
|
||||
|
||||
|
||||
@@ -1796,22 +1796,22 @@ lMangleStructName(const std::string &name, Variability variability) {
|
||||
default:
|
||||
FATAL("Unexpected variability in lMangleStructName()");
|
||||
}
|
||||
|
||||
|
||||
// And stuff the name at the end....
|
||||
n += name;
|
||||
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<SourcePos, 8> &ep,
|
||||
bool ic, Variability v, SourcePos p)
|
||||
: CollectionType(STRUCT_TYPE), name(n), elementTypes(elts), elementNames(en),
|
||||
bool ic, Variability v, SourcePos p)
|
||||
: CollectionType(STRUCT_TYPE), name(n), elementTypes(elts), elementNames(en),
|
||||
elementPositions(ep), variability(v), isConst(ic), pos(p) {
|
||||
oppositeConstStructType = NULL;
|
||||
finalElementTypes.resize(elts.size(), NULL);
|
||||
|
||||
|
||||
if (variability != Variability::Unbound) {
|
||||
// For structs with non-unbound variability, we'll create the
|
||||
// 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
|
||||
StructType::GetVariability() const {
|
||||
return variability;
|
||||
return variability;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
StructType::IsBoolType() const {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
StructType::IsFloatType() const {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
StructType::IsIntType() const {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
StructType::IsUnsignedType() const {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
StructType::IsConstType() const {
|
||||
return isConst;
|
||||
return isConst;
|
||||
}
|
||||
|
||||
|
||||
@@ -1917,7 +1917,7 @@ StructType::GetBaseType() const {
|
||||
|
||||
const StructType *
|
||||
StructType::GetAsVaryingType() const {
|
||||
if (IsVaryingType())
|
||||
if (IsVaryingType())
|
||||
return this;
|
||||
else
|
||||
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||
@@ -1927,7 +1927,7 @@ StructType::GetAsVaryingType() const {
|
||||
|
||||
const StructType *
|
||||
StructType::GetAsUniformType() const {
|
||||
if (IsUniformType())
|
||||
if (IsUniformType())
|
||||
return this;
|
||||
else
|
||||
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||
@@ -1937,7 +1937,7 @@ StructType::GetAsUniformType() const {
|
||||
|
||||
const StructType *
|
||||
StructType::GetAsUnboundVariabilityType() const {
|
||||
if (HasUnboundVariability())
|
||||
if (HasUnboundVariability())
|
||||
return this;
|
||||
else
|
||||
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||
@@ -1981,7 +1981,7 @@ StructType::GetAsConstType() const {
|
||||
else if (oppositeConstStructType != NULL)
|
||||
return oppositeConstStructType;
|
||||
else {
|
||||
oppositeConstStructType =
|
||||
oppositeConstStructType =
|
||||
new StructType(name, elementTypes, elementNames, elementPositions,
|
||||
true, variability, pos);
|
||||
oppositeConstStructType->oppositeConstStructType = this;
|
||||
@@ -1997,7 +1997,7 @@ StructType::GetAsNonConstType() const {
|
||||
else if (oppositeConstStructType != NULL)
|
||||
return oppositeConstStructType;
|
||||
else {
|
||||
oppositeConstStructType =
|
||||
oppositeConstStructType =
|
||||
new StructType(name, elementTypes, elementNames, elementPositions,
|
||||
false, variability, pos);
|
||||
oppositeConstStructType->oppositeConstStructType = this;
|
||||
@@ -2115,9 +2115,9 @@ StructType::GetDIType(llvm::DIDescriptor scope) const {
|
||||
|
||||
llvm::DIFile diFile = elementPositions[i].GetDIFile();
|
||||
int line = elementPositions[i].first_line;
|
||||
llvm::DIType fieldType =
|
||||
m->diBuilder->createMemberType(scope, elementNames[i], diFile,
|
||||
line, eltSize, eltAlign,
|
||||
llvm::DIType fieldType =
|
||||
m->diBuilder->createMemberType(scope, elementNames[i], diFile,
|
||||
line, eltSize, eltAlign,
|
||||
currentSize, 0, eltType);
|
||||
elementLLVMTypes.push_back(fieldType);
|
||||
|
||||
@@ -2201,7 +2201,7 @@ StructType::checkIfCanBeSOA(const StructType *st) {
|
||||
Error(st->elementPositions[i], "Unable to apply SOA conversion to "
|
||||
"struct due to \"%s\" member \"%s\" with bound \"%s\" "
|
||||
"variability.", eltType->GetString().c_str(),
|
||||
st->elementNames[i].c_str(),
|
||||
st->elementNames[i].c_str(),
|
||||
eltType->IsUniformType() ? "uniform" : "varying");
|
||||
ok = false;
|
||||
}
|
||||
@@ -2219,9 +2219,9 @@ StructType::checkIfCanBeSOA(const StructType *st) {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// UndefinedStructType
|
||||
|
||||
UndefinedStructType::UndefinedStructType(const std::string &n,
|
||||
UndefinedStructType::UndefinedStructType(const std::string &n,
|
||||
const Variability var, bool ic,
|
||||
SourcePos p)
|
||||
SourcePos p)
|
||||
: Type(UNDEFINED_STRUCT_TYPE), name(n), variability(var), isConst(ic), pos(p) {
|
||||
Assert(name != "");
|
||||
if (variability != Variability::Unbound) {
|
||||
@@ -2392,7 +2392,7 @@ UndefinedStructType::GetDIType(llvm::DIDescriptor scope) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ReferenceType
|
||||
|
||||
ReferenceType::ReferenceType(const Type *t)
|
||||
ReferenceType::ReferenceType(const Type *t)
|
||||
: Type(REFERENCE_TYPE), targetType(t) {
|
||||
asOtherConstType = NULL;
|
||||
}
|
||||
@@ -2404,7 +2404,7 @@ ReferenceType::GetVariability() const {
|
||||
Assert(m->errorCount > 0);
|
||||
return Variability(Variability::Unbound);
|
||||
}
|
||||
return targetType->GetVariability();
|
||||
return targetType->GetVariability();
|
||||
}
|
||||
|
||||
|
||||
@@ -2414,7 +2414,7 @@ ReferenceType::IsBoolType() const {
|
||||
Assert(m->errorCount > 0);
|
||||
return false;
|
||||
}
|
||||
return targetType->IsBoolType();
|
||||
return targetType->IsBoolType();
|
||||
}
|
||||
|
||||
|
||||
@@ -2424,7 +2424,7 @@ ReferenceType::IsFloatType() const {
|
||||
Assert(m->errorCount > 0);
|
||||
return false;
|
||||
}
|
||||
return targetType->IsFloatType();
|
||||
return targetType->IsFloatType();
|
||||
}
|
||||
|
||||
|
||||
@@ -2434,7 +2434,7 @@ ReferenceType::IsIntType() const {
|
||||
Assert(m->errorCount > 0);
|
||||
return false;
|
||||
}
|
||||
return targetType->IsIntType();
|
||||
return targetType->IsIntType();
|
||||
}
|
||||
|
||||
|
||||
@@ -2444,7 +2444,7 @@ ReferenceType::IsUnsignedType() const {
|
||||
Assert(m->errorCount > 0);
|
||||
return false;
|
||||
}
|
||||
return targetType->IsUnsignedType();
|
||||
return targetType->IsUnsignedType();
|
||||
}
|
||||
|
||||
|
||||
@@ -2480,7 +2480,7 @@ ReferenceType::GetAsVaryingType() const {
|
||||
Assert(m->errorCount > 0);
|
||||
return NULL;
|
||||
}
|
||||
if (IsVaryingType())
|
||||
if (IsVaryingType())
|
||||
return this;
|
||||
return new ReferenceType(targetType->GetAsVaryingType());
|
||||
}
|
||||
@@ -2492,7 +2492,7 @@ ReferenceType::GetAsUniformType() const {
|
||||
Assert(m->errorCount > 0);
|
||||
return NULL;
|
||||
}
|
||||
if (IsUniformType())
|
||||
if (IsUniformType())
|
||||
return this;
|
||||
return new ReferenceType(targetType->GetAsUniformType());
|
||||
}
|
||||
@@ -2504,7 +2504,7 @@ ReferenceType::GetAsUnboundVariabilityType() const {
|
||||
Assert(m->errorCount > 0);
|
||||
return NULL;
|
||||
}
|
||||
if (HasUnboundVariability())
|
||||
if (HasUnboundVariability())
|
||||
return this;
|
||||
return new ReferenceType(targetType->GetAsUnboundVariabilityType());
|
||||
}
|
||||
@@ -2525,7 +2525,7 @@ ReferenceType::ResolveUnboundVariability(Variability v) const {
|
||||
}
|
||||
return new ReferenceType(targetType->ResolveUnboundVariability(v));
|
||||
}
|
||||
|
||||
|
||||
|
||||
const ReferenceType *
|
||||
ReferenceType::GetAsConstType() const {
|
||||
@@ -2599,7 +2599,7 @@ ReferenceType::GetCDeclaration(const std::string &name) const {
|
||||
if (at->GetElementCount() == 0) {
|
||||
// emit unsized arrays as pointers to the base type..
|
||||
std::string ret;
|
||||
ret += at->GetElementType()->GetAsNonConstType()->GetCDeclaration("") +
|
||||
ret += at->GetElementType()->GetAsNonConstType()->GetCDeclaration("") +
|
||||
std::string(" *");
|
||||
if (lShouldPrintName(name))
|
||||
ret += name;
|
||||
@@ -2657,11 +2657,11 @@ ReferenceType::GetDIType(llvm::DIDescriptor scope) const {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// FunctionType
|
||||
|
||||
FunctionType::FunctionType(const Type *r,
|
||||
const llvm::SmallVector<const Type *, 8> &a,
|
||||
FunctionType::FunctionType(const Type *r,
|
||||
const llvm::SmallVector<const Type *, 8> &a,
|
||||
SourcePos p)
|
||||
: Type(FUNCTION_TYPE), isTask(false), isExported(false), isExternC(false),
|
||||
isUnmasked(false), returnType(r), paramTypes(a),
|
||||
: Type(FUNCTION_TYPE), isTask(false), isExported(false), isExternC(false),
|
||||
isUnmasked(false), returnType(r), paramTypes(a),
|
||||
paramNames(llvm::SmallVector<std::string, 8>(a.size(), "")),
|
||||
paramDefaults(llvm::SmallVector<Expr *, 8>(a.size(), NULL)),
|
||||
paramPositions(llvm::SmallVector<SourcePos, 8>(a.size(), p)) {
|
||||
@@ -2672,15 +2672,15 @@ FunctionType::FunctionType(const Type *r,
|
||||
|
||||
|
||||
FunctionType::FunctionType(const Type *r,
|
||||
const llvm::SmallVector<const Type *, 8> &a,
|
||||
const llvm::SmallVector<std::string, 8> &an,
|
||||
const llvm::SmallVector<const Type *, 8> &a,
|
||||
const llvm::SmallVector<std::string, 8> &an,
|
||||
const llvm::SmallVector<Expr *, 8> &ad,
|
||||
const llvm::SmallVector<SourcePos, 8> &ap,
|
||||
bool it, bool is, bool ec, bool ium)
|
||||
: Type(FUNCTION_TYPE), isTask(it), isExported(is), isExternC(ec),
|
||||
isUnmasked(ium), returnType(r), paramTypes(a), paramNames(an),
|
||||
: Type(FUNCTION_TYPE), isTask(it), isExported(is), isExternC(ec),
|
||||
isUnmasked(ium), returnType(r), paramTypes(a), paramNames(an),
|
||||
paramDefaults(ad), paramPositions(ap) {
|
||||
Assert(paramTypes.size() == paramNames.size() &&
|
||||
Assert(paramTypes.size() == paramNames.size() &&
|
||||
paramNames.size() == paramDefaults.size() &&
|
||||
paramDefaults.size() == paramPositions.size());
|
||||
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] "
|
||||
// versus "float (foo *)[4]").
|
||||
const PointerType *pt = CastType<PointerType>(type);
|
||||
if (pt != NULL &&
|
||||
if (pt != NULL &&
|
||||
CastType<ArrayType>(pt->GetBaseType()) != NULL) {
|
||||
type = new ArrayType(pt->GetBaseType(), 0);
|
||||
}
|
||||
@@ -2883,10 +2883,10 @@ FunctionType::GetDIType(llvm::DIDescriptor scope) const {
|
||||
retArgTypes.push_back(t->GetDIType(scope));
|
||||
}
|
||||
|
||||
llvm::DIArray retArgTypesArray =
|
||||
llvm::DIArray retArgTypesArray =
|
||||
m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(retArgTypes));
|
||||
llvm::DIType diType =
|
||||
// FIXME: DIFile
|
||||
llvm::DIType diType =
|
||||
// FIXME: DIFile
|
||||
m->diBuilder->createSubroutineType(llvm::DIFile(), retArgTypesArray);
|
||||
return diType;
|
||||
}
|
||||
@@ -2906,7 +2906,7 @@ FunctionType::GetReturnTypeString() const {
|
||||
ret += "extern \"C\" ";
|
||||
if (isUnmasked)
|
||||
ret += "unmasked ";
|
||||
if (isSafe)
|
||||
if (isSafe)
|
||||
ret += "/*safe*/ ";
|
||||
if (costOverride > 0) {
|
||||
char buf[32];
|
||||
@@ -2920,7 +2920,7 @@ FunctionType::GetReturnTypeString() const {
|
||||
|
||||
llvm::FunctionType *
|
||||
FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
|
||||
if (isTask == true)
|
||||
if (isTask == true)
|
||||
Assert(removeMask == false);
|
||||
|
||||
// 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
|
||||
}
|
||||
else
|
||||
// Otherwise we already have the types of the arguments
|
||||
// Otherwise we already have the types of the arguments
|
||||
callTypes = llvmArgTypes;
|
||||
|
||||
if (returnType == NULL) {
|
||||
@@ -2976,30 +2976,30 @@ FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
|
||||
|
||||
|
||||
const Type *
|
||||
FunctionType::GetParameterType(int i) const {
|
||||
FunctionType::GetParameterType(int i) const {
|
||||
Assert(i < (int)paramTypes.size());
|
||||
return paramTypes[i];
|
||||
}
|
||||
|
||||
|
||||
Expr *
|
||||
FunctionType::GetParameterDefault(int i) const {
|
||||
FunctionType::GetParameterDefault(int i) const {
|
||||
Assert(i < (int)paramDefaults.size());
|
||||
return paramDefaults[i];
|
||||
return paramDefaults[i];
|
||||
}
|
||||
|
||||
|
||||
const SourcePos &
|
||||
FunctionType::GetParameterSourcePos(int i) const {
|
||||
FunctionType::GetParameterSourcePos(int i) const {
|
||||
Assert(i < (int)paramPositions.size());
|
||||
return paramPositions[i];
|
||||
}
|
||||
|
||||
|
||||
const std::string &
|
||||
FunctionType::GetParameterName(int i) const {
|
||||
FunctionType::GetParameterName(int i) const {
|
||||
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->GetElementCount() != vecSize) {
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
@@ -3049,7 +3049,7 @@ lVectorConvert(const Type *type, SourcePos pos, const char *reason, int vecSize)
|
||||
|
||||
|
||||
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) {
|
||||
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.
|
||||
if (Type::Equal(t0, t1))
|
||||
if (Type::Equal(t0, t1))
|
||||
return t0;
|
||||
|
||||
|
||||
// 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
|
||||
// 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(),
|
||||
pos, reason, forceVarying);
|
||||
if (!t)
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
// 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
|
||||
// return NULL if t1 is e.g. an array type and it's illegal to have
|
||||
// a vector of it..
|
||||
const Type *t = MoreGeneralType(vt0->GetElementType(), t1, pos,
|
||||
const Type *t = MoreGeneralType(vt0->GetElementType(), t1, pos,
|
||||
reason, forceVarying);
|
||||
if (!t)
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
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) {
|
||||
// As in the above case, see if we can promote t0 to make a vector
|
||||
// that matches vt1.
|
||||
const Type *t = MoreGeneralType(t0, vt1->GetElementType(), pos,
|
||||
const Type *t = MoreGeneralType(t0, vt1->GetElementType(), pos,
|
||||
reason, forceVarying);
|
||||
if (!t)
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
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 *atb = CastType<AtomicType>(b);
|
||||
if (ata != NULL && atb != NULL) {
|
||||
return ((ata->basicType == atb->basicType) &&
|
||||
return ((ata->basicType == atb->basicType) &&
|
||||
(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 *artb = CastType<ArrayType>(b);
|
||||
if (arta != NULL && artb != NULL)
|
||||
return (arta->GetElementCount() == artb->GetElementCount() &&
|
||||
lCheckTypeEquality(arta->GetElementType(), artb->GetElementType(),
|
||||
return (arta->GetElementCount() == artb->GetElementCount() &&
|
||||
lCheckTypeEquality(arta->GetElementType(), artb->GetElementType(),
|
||||
ignoreConst));
|
||||
|
||||
const VectorType *vta = CastType<VectorType>(a);
|
||||
const VectorType *vtb = CastType<VectorType>(b);
|
||||
if (vta != NULL && vtb != NULL)
|
||||
return (vta->GetElementCount() == vtb->GetElementCount() &&
|
||||
return (vta->GetElementCount() == vtb->GetElementCount() &&
|
||||
lCheckTypeEquality(vta->GetElementType(), vtb->GetElementType(),
|
||||
ignoreConst));
|
||||
|
||||
@@ -3272,7 +3272,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
|
||||
if (a->GetVariability() != b->GetVariability())
|
||||
return false;
|
||||
|
||||
const std::string &namea = sta ? sta->GetStructName() :
|
||||
const std::string &namea = sta ? sta->GetStructName() :
|
||||
usta->GetStructName();
|
||||
const std::string &nameb = stb ? stb->GetStructName() :
|
||||
ustb->GetStructName();
|
||||
@@ -3285,7 +3285,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
|
||||
return (pta->IsUniformType() == ptb->IsUniformType() &&
|
||||
pta->IsSlice() == ptb->IsSlice() &&
|
||||
pta->IsFrozenSlice() == ptb->IsFrozenSlice() &&
|
||||
lCheckTypeEquality(pta->GetBaseType(), ptb->GetBaseType(),
|
||||
lCheckTypeEquality(pta->GetBaseType(), ptb->GetBaseType(),
|
||||
ignoreConst));
|
||||
|
||||
const ReferenceType *rta = CastType<ReferenceType>(a);
|
||||
@@ -3299,7 +3299,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
|
||||
if (fta != NULL && ftb != NULL) {
|
||||
// Both the return types and all of the argument types must match
|
||||
// for function types to match
|
||||
if (!lCheckTypeEquality(fta->GetReturnType(), ftb->GetReturnType(),
|
||||
if (!lCheckTypeEquality(fta->GetReturnType(), ftb->GetReturnType(),
|
||||
ignoreConst))
|
||||
return false;
|
||||
|
||||
|
||||
70
type.h
70
type.h
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -53,17 +53,17 @@ class ConstExpr;
|
||||
class StructType;
|
||||
|
||||
/** 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 {
|
||||
enum VarType { Unbound, Uniform, Varying, SOA };
|
||||
|
||||
Variability(VarType t = Unbound, int w = 0) : type(t), soaWidth(w) { }
|
||||
|
||||
bool operator==(const Variability &v) const {
|
||||
return v.type == type && v.soaWidth == soaWidth;
|
||||
bool operator==(const Variability &v) const {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ struct Variability {
|
||||
|
||||
std::string GetString() const;
|
||||
std::string MangleString() const;
|
||||
|
||||
|
||||
VarType type;
|
||||
int soaWidth;
|
||||
};
|
||||
@@ -122,19 +122,19 @@ public:
|
||||
|
||||
/** Returns true if the underlying type is either a pointer type */
|
||||
bool IsPointerType() const;
|
||||
|
||||
|
||||
/** Returns true if the underlying type is a array type */
|
||||
bool IsArrayType() const;
|
||||
|
||||
|
||||
/** Returns true if the underlying type is a array type */
|
||||
bool IsReferenceType() const;
|
||||
|
||||
|
||||
/** Returns true if the underlying type is either a pointer or an array */
|
||||
bool IsVoidType() const;
|
||||
|
||||
/** Returns true if this type is 'const'-qualified. */
|
||||
virtual bool IsConstType() const = 0;
|
||||
|
||||
|
||||
/** Returns true if the underlying type is a float or integer type. */
|
||||
bool IsNumericType() const { return IsFloatType() || IsIntType(); }
|
||||
|
||||
@@ -142,13 +142,13 @@ public:
|
||||
virtual Variability GetVariability() const = 0;
|
||||
|
||||
/** Returns true if the underlying type is uniform */
|
||||
bool IsUniformType() const {
|
||||
return GetVariability() == Variability::Uniform;
|
||||
bool IsUniformType() const {
|
||||
return GetVariability() == Variability::Uniform;
|
||||
}
|
||||
|
||||
/** Returns true if the underlying type is varying */
|
||||
bool IsVaryingType() const {
|
||||
return GetVariability() == Variability::Varying;
|
||||
bool IsVaryingType() const {
|
||||
return GetVariability() == Variability::Varying;
|
||||
}
|
||||
|
||||
/** 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
|
||||
unbound. */
|
||||
bool HasUnboundVariability() const {
|
||||
return GetVariability() == Variability::Unbound;
|
||||
bool HasUnboundVariability() const {
|
||||
return GetVariability() == Variability::Unbound;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
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. */
|
||||
virtual const Type *GetAsConstType() const = 0;
|
||||
|
||||
@@ -244,7 +244,7 @@ public:
|
||||
needed.
|
||||
@param reason String describing the context of why the general
|
||||
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".
|
||||
@param vecSize The vector size of the returned type. If non-zero,
|
||||
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
|
||||
factored out and done separately in the cases when needed.
|
||||
|
||||
|
||||
*/
|
||||
static const Type *MoreGeneralType(const Type *type0, const Type *type1,
|
||||
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
|
||||
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::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. */
|
||||
enum BasicType {
|
||||
TYPE_VOID,
|
||||
@@ -431,7 +431,7 @@ private:
|
||||
*/
|
||||
class PointerType : public Type {
|
||||
public:
|
||||
PointerType(const Type *t, Variability v, bool isConst,
|
||||
PointerType(const Type *t, Variability v, bool isConst,
|
||||
bool isSlice = false, bool frozen = false);
|
||||
|
||||
/** 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
|
||||
VectorTypes all inherit from.
|
||||
*/
|
||||
*/
|
||||
class CollectionType : public Type {
|
||||
public:
|
||||
/** 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
|
||||
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 {
|
||||
public:
|
||||
@@ -592,7 +592,7 @@ public:
|
||||
any array dimensions that are unsized according to the number of
|
||||
elements in the corresponding sectoin of the initializer
|
||||
expression.
|
||||
*/
|
||||
*/
|
||||
static const Type *SizeUnsizedArrays(const Type *type, Expr *initExpr);
|
||||
|
||||
private:
|
||||
@@ -663,9 +663,9 @@ private:
|
||||
*/
|
||||
class StructType : public CollectionType {
|
||||
public:
|
||||
StructType(const std::string &name, const llvm::SmallVector<const Type *, 8> &elts,
|
||||
const llvm::SmallVector<std::string, 8> &eltNames,
|
||||
const llvm::SmallVector<SourcePos, 8> &eltPositions, bool isConst,
|
||||
StructType(const std::string &name, const llvm::SmallVector<const Type *, 8> &elts,
|
||||
const llvm::SmallVector<std::string, 8> &eltNames,
|
||||
const llvm::SmallVector<SourcePos, 8> &eltPositions, bool isConst,
|
||||
Variability variability, SourcePos pos);
|
||||
|
||||
Variability GetVariability() const;
|
||||
@@ -707,7 +707,7 @@ public:
|
||||
|
||||
/** Returns the name of the i'th element of the structure. */
|
||||
const std::string &GetElementName(int i) const { return elementNames[i]; }
|
||||
|
||||
|
||||
/** Returns the total number of elements in the structure. */
|
||||
int GetElementCount() const { return int(elementTypes.size()); }
|
||||
|
||||
@@ -842,9 +842,9 @@ private:
|
||||
*/
|
||||
class FunctionType : public Type {
|
||||
public:
|
||||
FunctionType(const Type *returnType,
|
||||
FunctionType(const Type *returnType,
|
||||
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<std::string, 8> &argNames,
|
||||
const llvm::SmallVector<Expr *, 8> &argDefaults,
|
||||
@@ -884,7 +884,7 @@ public:
|
||||
function type. The \c disableMask parameter indicates whether the
|
||||
llvm::FunctionType should have the trailing mask parameter, if
|
||||
present, removed from the return function signature. */
|
||||
llvm::FunctionType *LLVMFunctionType(llvm::LLVMContext *ctx,
|
||||
llvm::FunctionType *LLVMFunctionType(llvm::LLVMContext *ctx,
|
||||
bool disableMask = false) const;
|
||||
|
||||
int GetNumParameters() const { return (int)paramTypes.size(); }
|
||||
@@ -915,7 +915,7 @@ public:
|
||||
bool isSafe;
|
||||
|
||||
/** If non-negative, this provides a user-supplied override to the cost
|
||||
function estimate for the function. */
|
||||
function estimate for the function. */
|
||||
int costOverride;
|
||||
|
||||
private:
|
||||
@@ -993,7 +993,7 @@ template <> inline const SequentialType *
|
||||
CastType(const Type *type) {
|
||||
// Note that this function must be updated if other sequential type
|
||||
// implementations are added.
|
||||
if (type != NULL &&
|
||||
if (type != NULL &&
|
||||
(type->typeId == ARRAY_TYPE || type->typeId == VECTOR_TYPE))
|
||||
return (const SequentialType *)type;
|
||||
else
|
||||
@@ -1004,7 +1004,7 @@ template <> inline const CollectionType *
|
||||
CastType(const Type *type) {
|
||||
// Similarly a new collection type implementation requires updating
|
||||
// this function.
|
||||
if (type != NULL &&
|
||||
if (type != NULL &&
|
||||
(type->typeId == ARRAY_TYPE || type->typeId == VECTOR_TYPE ||
|
||||
type->typeId == STRUCT_TYPE))
|
||||
return (const CollectionType *)type;
|
||||
|
||||
24
util.cpp
24
util.cpp
@@ -28,7 +28,7 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
@@ -139,7 +139,7 @@ lResetColor() {
|
||||
}
|
||||
|
||||
/** 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 *
|
||||
lFindWordEnd(const char *buf) {
|
||||
@@ -166,7 +166,7 @@ lPrintFileLineContext(SourcePos p) {
|
||||
while ((c = fgetc(f)) != EOF) {
|
||||
// Don't print more than three lines of context. (More than that,
|
||||
// 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)
|
||||
fputc(c, stderr);
|
||||
if (c == '\n')
|
||||
@@ -322,7 +322,7 @@ asprintf(char **sptr, const char *fmt, ...)
|
||||
@param args Arguments with values for format string % entries
|
||||
*/
|
||||
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) {
|
||||
char *errorBuf, *formattedBuf;
|
||||
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
|
||||
if (asprintf(&formattedBuf, "%s%s%s%s%s: %s%s", lStartBold(),
|
||||
isError ? lStartRed() : lStartBlue(), type,
|
||||
lResetColor(), lStartBold(), errorBuf,
|
||||
lResetColor(), lStartBold(), errorBuf,
|
||||
lResetColor()) == -1) {
|
||||
fprintf(stderr, "asprintf() unable to allocate memory!\n");
|
||||
exit(1);
|
||||
@@ -344,10 +344,10 @@ lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
|
||||
}
|
||||
else {
|
||||
// Create an error message that includes the file and line number
|
||||
if (asprintf(&formattedBuf, "%s%s:%d:%d: %s%s%s%s: %s%s",
|
||||
lStartBold(), p.name, p.first_line, p.first_column,
|
||||
isError ? lStartRed() : lStartBlue(), type,
|
||||
lResetColor(), lStartBold(), errorBuf,
|
||||
if (asprintf(&formattedBuf, "%s%s:%d:%d: %s%s%s%s: %s%s",
|
||||
lStartBold(), p.name, p.first_line, p.first_column,
|
||||
isError ? lStartRed() : lStartBlue(), type,
|
||||
lResetColor(), lStartBold(), errorBuf,
|
||||
lResetColor()) == -1) {
|
||||
fprintf(stderr, "asprintf() unable to allocate memory!\n");
|
||||
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) {
|
||||
if (str.size() == 0 || (str.size() == 1 && !isalpha(str[0])))
|
||||
// don't even try...
|
||||
@@ -536,7 +536,7 @@ MatchStrings(const std::string &str, const std::vector<std::string> &options) {
|
||||
|
||||
|
||||
void
|
||||
GetDirectoryAndFileName(const std::string ¤tDirectory,
|
||||
GetDirectoryAndFileName(const std::string ¤tDirectory,
|
||||
const std::string &relativeName,
|
||||
std::string *directory, std::string *filename) {
|
||||
#ifdef ISPC_IS_WINDOWS
|
||||
@@ -550,7 +550,7 @@ GetDirectoryAndFileName(const std::string ¤tDirectory,
|
||||
#else
|
||||
// We need a fully qualified path. First, see if the current file name
|
||||
// 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...
|
||||
std::string fullPath;
|
||||
if (relativeName[0] == '/')
|
||||
|
||||
16
util.h
16
util.h
@@ -28,12 +28,12 @@
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
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
|
||||
|
||||
@brief
|
||||
@brief
|
||||
*/
|
||||
|
||||
#ifndef ISPC_UTIL_H
|
||||
@@ -50,9 +50,9 @@ struct SourcePos;
|
||||
of two already. */
|
||||
inline uint32_t RoundUpPow2(uint32_t v) {
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
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
|
||||
position to associate with the message, a printf()-style format string
|
||||
is passed along with any values needed for items in the format
|
||||
string.
|
||||
string.
|
||||
*/
|
||||
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
|
||||
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.
|
||||
format string.
|
||||
*/
|
||||
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
|
||||
position to associate with the message, a printf()-style format string
|
||||
is passed along with any values needed for items in the format
|
||||
string.
|
||||
string.
|
||||
*/
|
||||
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
|
||||
directory, this function returns the final directory that the resulting
|
||||
file is in and the base name of the file itself. */
|
||||
void GetDirectoryAndFileName(const std::string ¤tDir,
|
||||
void GetDirectoryAndFileName(const std::string ¤tDir,
|
||||
const std::string &relativeName,
|
||||
std::string *directory, std::string *filename);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user