Merge pull request #444 from dbabokin/master
Fixing tabs and trainling white spaces
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
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file ast.cpp
|
/** @file ast.cpp
|
||||||
@@ -109,20 +109,20 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
|
|||||||
es->expr = (Expr *)WalkAST(es->expr, preFunc, postFunc, data);
|
es->expr = (Expr *)WalkAST(es->expr, preFunc, postFunc, data);
|
||||||
else if ((ds = dynamic_cast<DeclStmt *>(node)) != NULL) {
|
else if ((ds = dynamic_cast<DeclStmt *>(node)) != NULL) {
|
||||||
for (unsigned int i = 0; i < ds->vars.size(); ++i)
|
for (unsigned int i = 0; i < ds->vars.size(); ++i)
|
||||||
ds->vars[i].init = (Expr *)WalkAST(ds->vars[i].init, preFunc,
|
ds->vars[i].init = (Expr *)WalkAST(ds->vars[i].init, preFunc,
|
||||||
postFunc, data);
|
postFunc, data);
|
||||||
}
|
}
|
||||||
else if ((is = dynamic_cast<IfStmt *>(node)) != NULL) {
|
else if ((is = dynamic_cast<IfStmt *>(node)) != NULL) {
|
||||||
is->test = (Expr *)WalkAST(is->test, preFunc, postFunc, data);
|
is->test = (Expr *)WalkAST(is->test, preFunc, postFunc, data);
|
||||||
is->trueStmts = (Stmt *)WalkAST(is->trueStmts, preFunc,
|
is->trueStmts = (Stmt *)WalkAST(is->trueStmts, preFunc,
|
||||||
postFunc, data);
|
postFunc, data);
|
||||||
is->falseStmts = (Stmt *)WalkAST(is->falseStmts, preFunc,
|
is->falseStmts = (Stmt *)WalkAST(is->falseStmts, preFunc,
|
||||||
postFunc, data);
|
postFunc, data);
|
||||||
}
|
}
|
||||||
else if ((dos = dynamic_cast<DoStmt *>(node)) != NULL) {
|
else if ((dos = dynamic_cast<DoStmt *>(node)) != NULL) {
|
||||||
dos->testExpr = (Expr *)WalkAST(dos->testExpr, preFunc,
|
dos->testExpr = (Expr *)WalkAST(dos->testExpr, preFunc,
|
||||||
postFunc, data);
|
postFunc, data);
|
||||||
dos->bodyStmts = (Stmt *)WalkAST(dos->bodyStmts, preFunc,
|
dos->bodyStmts = (Stmt *)WalkAST(dos->bodyStmts, preFunc,
|
||||||
postFunc, data);
|
postFunc, data);
|
||||||
}
|
}
|
||||||
else if ((fs = dynamic_cast<ForStmt *>(node)) != NULL) {
|
else if ((fs = dynamic_cast<ForStmt *>(node)) != NULL) {
|
||||||
@@ -133,10 +133,10 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
|
|||||||
}
|
}
|
||||||
else if ((fes = dynamic_cast<ForeachStmt *>(node)) != NULL) {
|
else if ((fes = dynamic_cast<ForeachStmt *>(node)) != NULL) {
|
||||||
for (unsigned int i = 0; i < fes->startExprs.size(); ++i)
|
for (unsigned int i = 0; i < fes->startExprs.size(); ++i)
|
||||||
fes->startExprs[i] = (Expr *)WalkAST(fes->startExprs[i], preFunc,
|
fes->startExprs[i] = (Expr *)WalkAST(fes->startExprs[i], preFunc,
|
||||||
postFunc, data);
|
postFunc, data);
|
||||||
for (unsigned int i = 0; i < fes->endExprs.size(); ++i)
|
for (unsigned int i = 0; i < fes->endExprs.size(); ++i)
|
||||||
fes->endExprs[i] = (Expr *)WalkAST(fes->endExprs[i], preFunc,
|
fes->endExprs[i] = (Expr *)WalkAST(fes->endExprs[i], preFunc,
|
||||||
postFunc, data);
|
postFunc, data);
|
||||||
fes->stmts = (Stmt *)WalkAST(fes->stmts, preFunc, postFunc, data);
|
fes->stmts = (Stmt *)WalkAST(fes->stmts, preFunc, postFunc, data);
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,7 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
|
|||||||
}
|
}
|
||||||
else if ((el = dynamic_cast<ExprList *>(node)) != NULL) {
|
else if ((el = dynamic_cast<ExprList *>(node)) != NULL) {
|
||||||
for (unsigned int i = 0; i < el->exprs.size(); ++i)
|
for (unsigned int i = 0; i < el->exprs.size(); ++i)
|
||||||
el->exprs[i] = (Expr *)WalkAST(el->exprs[i], preFunc,
|
el->exprs[i] = (Expr *)WalkAST(el->exprs[i], preFunc,
|
||||||
postFunc, data);
|
postFunc, data);
|
||||||
}
|
}
|
||||||
else if ((fce = dynamic_cast<FunctionCallExpr *>(node)) != NULL) {
|
else if ((fce = dynamic_cast<FunctionCallExpr *>(node)) != NULL) {
|
||||||
@@ -247,9 +247,9 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
|
|||||||
else if ((aoe = dynamic_cast<AddressOfExpr *>(node)) != NULL)
|
else if ((aoe = dynamic_cast<AddressOfExpr *>(node)) != NULL)
|
||||||
aoe->expr = (Expr *)WalkAST(aoe->expr, preFunc, postFunc, data);
|
aoe->expr = (Expr *)WalkAST(aoe->expr, preFunc, postFunc, data);
|
||||||
else if ((newe = dynamic_cast<NewExpr *>(node)) != NULL) {
|
else if ((newe = dynamic_cast<NewExpr *>(node)) != NULL) {
|
||||||
newe->countExpr = (Expr *)WalkAST(newe->countExpr, preFunc,
|
newe->countExpr = (Expr *)WalkAST(newe->countExpr, preFunc,
|
||||||
postFunc, data);
|
postFunc, data);
|
||||||
newe->initExpr = (Expr *)WalkAST(newe->initExpr, preFunc,
|
newe->initExpr = (Expr *)WalkAST(newe->initExpr, preFunc,
|
||||||
postFunc, data);
|
postFunc, data);
|
||||||
}
|
}
|
||||||
else if (dynamic_cast<SymbolExpr *>(node) != NULL ||
|
else if (dynamic_cast<SymbolExpr *>(node) != NULL ||
|
||||||
@@ -257,9 +257,9 @@ WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc,
|
|||||||
dynamic_cast<FunctionSymbolExpr *>(node) != NULL ||
|
dynamic_cast<FunctionSymbolExpr *>(node) != NULL ||
|
||||||
dynamic_cast<SyncExpr *>(node) != NULL ||
|
dynamic_cast<SyncExpr *>(node) != NULL ||
|
||||||
dynamic_cast<NullPointerExpr *>(node) != NULL) {
|
dynamic_cast<NullPointerExpr *>(node) != NULL) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
FATAL("Unhandled expression type in WalkAST().");
|
FATAL("Unhandled expression type in WalkAST().");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
ast.h
10
ast.h
@@ -28,11 +28,11 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file ast.h
|
/** @file ast.h
|
||||||
@brief
|
@brief
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ISPC_AST_H
|
#ifndef ISPC_AST_H
|
||||||
@@ -121,12 +121,12 @@ extern ASTNode *Optimize(ASTNode *root);
|
|||||||
|
|
||||||
/** Convenience version of Optimize() for Expr *s that returns an Expr *
|
/** Convenience version of Optimize() for Expr *s that returns an Expr *
|
||||||
(rather than an ASTNode *, which would require the caller to cast back
|
(rather than an ASTNode *, which would require the caller to cast back
|
||||||
to an Expr *). */
|
to an Expr *). */
|
||||||
extern Expr *Optimize(Expr *);
|
extern Expr *Optimize(Expr *);
|
||||||
|
|
||||||
/** Convenience version of Optimize() for Expr *s that returns an Stmt *
|
/** Convenience version of Optimize() for Expr *s that returns an Stmt *
|
||||||
(rather than an ASTNode *, which would require the caller to cast back
|
(rather than an ASTNode *, which would require the caller to cast back
|
||||||
to a Stmt *). */
|
to a Stmt *). */
|
||||||
extern Stmt *Optimize(Stmt *);
|
extern Stmt *Optimize(Stmt *);
|
||||||
|
|
||||||
/** Perform type-checking on the given AST (or portion of one), returning a
|
/** Perform type-checking on the given AST (or portion of one), returning a
|
||||||
@@ -144,7 +144,7 @@ extern Stmt *TypeCheck(Stmt *);
|
|||||||
extern int EstimateCost(ASTNode *root);
|
extern int EstimateCost(ASTNode *root);
|
||||||
|
|
||||||
/** Returns true if it would be safe to run the given code with an "all
|
/** Returns true if it would be safe to run the given code with an "all
|
||||||
off" mask. */
|
off" mask. */
|
||||||
extern bool SafeToRunWithMaskAllOff(ASTNode *root);
|
extern bool SafeToRunWithMaskAllOff(ASTNode *root);
|
||||||
|
|
||||||
#endif // ISPC_AST_H
|
#endif // ISPC_AST_H
|
||||||
|
|||||||
100
builtins.cpp
100
builtins.cpp
@@ -28,11 +28,11 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file builtins.cpp
|
/** @file builtins.cpp
|
||||||
@brief Definitions of functions related to setting up the standard library
|
@brief Definitions of functions related to setting up the standard library
|
||||||
and other builtins.
|
and other builtins.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -169,9 +169,9 @@ lLLVMTypeToISPCType(const llvm::Type *t, bool intAsUnsigned) {
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lCreateSymbol(const std::string &name, const Type *returnType,
|
lCreateSymbol(const std::string &name, const Type *returnType,
|
||||||
llvm::SmallVector<const Type *, 8> &argTypes,
|
llvm::SmallVector<const Type *, 8> &argTypes,
|
||||||
const llvm::FunctionType *ftype, llvm::Function *func,
|
const llvm::FunctionType *ftype, llvm::Function *func,
|
||||||
SymbolTable *symbolTable) {
|
SymbolTable *symbolTable) {
|
||||||
SourcePos noPos;
|
SourcePos noPos;
|
||||||
noPos.name = "__stdlib";
|
noPos.name = "__stdlib";
|
||||||
@@ -251,7 +251,7 @@ lCreateISPCSymbol(llvm::Function *func, SymbolTable *symbolTable) {
|
|||||||
"representable for builtin %s", j, name.c_str());
|
"representable for builtin %s", j, name.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
anyIntArgs |=
|
anyIntArgs |=
|
||||||
(Type::Equal(type, lLLVMTypeToISPCType(llvmArgType, !intAsUnsigned)) == false);
|
(Type::Equal(type, lLLVMTypeToISPCType(llvmArgType, !intAsUnsigned)) == false);
|
||||||
argTypes.push_back(type);
|
argTypes.push_back(type);
|
||||||
}
|
}
|
||||||
@@ -286,7 +286,7 @@ lAddModuleSymbols(llvm::Module *module, SymbolTable *symbolTable) {
|
|||||||
|
|
||||||
/** In many of the builtins-*.ll files, we have declarations of various LLVM
|
/** In many of the builtins-*.ll files, we have declarations of various LLVM
|
||||||
intrinsics that are then used in the implementation of various target-
|
intrinsics that are then used in the implementation of various target-
|
||||||
specific functions. This function loops over all of the intrinsic
|
specific functions. This function loops over all of the intrinsic
|
||||||
declarations and makes sure that the signature we have in our .ll file
|
declarations and makes sure that the signature we have in our .ll file
|
||||||
matches the signature of the actual intrinsic.
|
matches the signature of the actual intrinsic.
|
||||||
*/
|
*/
|
||||||
@@ -304,7 +304,7 @@ lCheckModuleIntrinsics(llvm::Module *module) {
|
|||||||
if (!strncmp(funcName.c_str(), "llvm.x86.", 9)) {
|
if (!strncmp(funcName.c_str(), "llvm.x86.", 9)) {
|
||||||
llvm::Intrinsic::ID id = (llvm::Intrinsic::ID)func->getIntrinsicID();
|
llvm::Intrinsic::ID id = (llvm::Intrinsic::ID)func->getIntrinsicID();
|
||||||
Assert(id != 0);
|
Assert(id != 0);
|
||||||
llvm::Type *intrinsicType =
|
llvm::Type *intrinsicType =
|
||||||
llvm::Intrinsic::getType(*g->ctx, id);
|
llvm::Intrinsic::getType(*g->ctx, id);
|
||||||
intrinsicType = llvm::PointerType::get(intrinsicType, 0);
|
intrinsicType = llvm::PointerType::get(intrinsicType, 0);
|
||||||
Assert(func->getType() == intrinsicType);
|
Assert(func->getType() == intrinsicType);
|
||||||
@@ -410,7 +410,7 @@ lSetInternalFunctions(llvm::Module *module) {
|
|||||||
"__delete_varying",
|
"__delete_varying",
|
||||||
"__do_assert_uniform",
|
"__do_assert_uniform",
|
||||||
"__do_assert_varying",
|
"__do_assert_varying",
|
||||||
"__do_print",
|
"__do_print",
|
||||||
"__doublebits_uniform_int64",
|
"__doublebits_uniform_int64",
|
||||||
"__doublebits_varying_int64",
|
"__doublebits_varying_int64",
|
||||||
"__exclusive_scan_add_double",
|
"__exclusive_scan_add_double",
|
||||||
@@ -654,7 +654,7 @@ AddBitcodeToModule(const unsigned char *bitcode, int length,
|
|||||||
bcModule->setDataLayout(module->getDataLayout());
|
bcModule->setDataLayout(module->getDataLayout());
|
||||||
|
|
||||||
std::string(linkError);
|
std::string(linkError);
|
||||||
if (llvm::Linker::LinkModules(module, bcModule,
|
if (llvm::Linker::LinkModules(module, bcModule,
|
||||||
llvm::Linker::DestroySource,
|
llvm::Linker::DestroySource,
|
||||||
&linkError))
|
&linkError))
|
||||||
Error(SourcePos(), "Error linking stdlib bitcode: %s", linkError.c_str());
|
Error(SourcePos(), "Error linking stdlib bitcode: %s", linkError.c_str());
|
||||||
@@ -672,7 +672,7 @@ AddBitcodeToModule(const unsigned char *bitcode, int length,
|
|||||||
static void
|
static void
|
||||||
lDefineConstantInt(const char *name, int val, llvm::Module *module,
|
lDefineConstantInt(const char *name, int val, llvm::Module *module,
|
||||||
SymbolTable *symbolTable) {
|
SymbolTable *symbolTable) {
|
||||||
Symbol *sym =
|
Symbol *sym =
|
||||||
new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(),
|
new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(),
|
||||||
SC_STATIC);
|
SC_STATIC);
|
||||||
sym->constValue = new ConstExpr(sym->type, val, SourcePos());
|
sym->constValue = new ConstExpr(sym->type, val, SourcePos());
|
||||||
@@ -694,8 +694,8 @@ lDefineConstantInt(const char *name, int val, llvm::Module *module,
|
|||||||
// FIXME? DWARF says that this (and programIndex below) should
|
// FIXME? DWARF says that this (and programIndex below) should
|
||||||
// have the DW_AT_artifical attribute. It's not clear if this
|
// have the DW_AT_artifical attribute. It's not clear if this
|
||||||
// matters for anything though.
|
// matters for anything though.
|
||||||
llvm::DIGlobalVariable var =
|
llvm::DIGlobalVariable var =
|
||||||
m->diBuilder->createGlobalVariable(name,
|
m->diBuilder->createGlobalVariable(name,
|
||||||
file,
|
file,
|
||||||
0 /* line */,
|
0 /* line */,
|
||||||
diType,
|
diType,
|
||||||
@@ -732,8 +732,8 @@ lDefineConstantIntFunc(const char *name, int val, llvm::Module *module,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) {
|
lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) {
|
||||||
Symbol *sym =
|
Symbol *sym =
|
||||||
new Symbol("programIndex", SourcePos(),
|
new Symbol("programIndex", SourcePos(),
|
||||||
AtomicType::VaryingInt32->GetAsConstType(), SC_STATIC);
|
AtomicType::VaryingInt32->GetAsConstType(), SC_STATIC);
|
||||||
|
|
||||||
int pi[ISPC_MAX_NVEC];
|
int pi[ISPC_MAX_NVEC];
|
||||||
@@ -755,7 +755,7 @@ lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) {
|
|||||||
llvm::DIType diType = sym->type->GetDIType(file);
|
llvm::DIType diType = sym->type->GetDIType(file);
|
||||||
Assert(diType.Verify());
|
Assert(diType.Verify());
|
||||||
llvm::DIGlobalVariable var =
|
llvm::DIGlobalVariable var =
|
||||||
m->diBuilder->createGlobalVariable(sym->name.c_str(),
|
m->diBuilder->createGlobalVariable(sym->name.c_str(),
|
||||||
file,
|
file,
|
||||||
0 /* line */,
|
0 /* line */,
|
||||||
diType,
|
diType,
|
||||||
@@ -773,13 +773,13 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
|||||||
if (g->target.is32Bit) {
|
if (g->target.is32Bit) {
|
||||||
extern unsigned char builtins_bitcode_c_32[];
|
extern unsigned char builtins_bitcode_c_32[];
|
||||||
extern int builtins_bitcode_c_32_length;
|
extern int builtins_bitcode_c_32_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_c_32, builtins_bitcode_c_32_length,
|
AddBitcodeToModule(builtins_bitcode_c_32, builtins_bitcode_c_32_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
extern unsigned char builtins_bitcode_c_64[];
|
extern unsigned char builtins_bitcode_c_64[];
|
||||||
extern int builtins_bitcode_c_64_length;
|
extern int builtins_bitcode_c_64_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_c_64, builtins_bitcode_c_64_length,
|
AddBitcodeToModule(builtins_bitcode_c_64, builtins_bitcode_c_64_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,12 +792,12 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
|||||||
extern unsigned char builtins_bitcode_sse2_x2[];
|
extern unsigned char builtins_bitcode_sse2_x2[];
|
||||||
extern int builtins_bitcode_sse2_x2_length;
|
extern int builtins_bitcode_sse2_x2_length;
|
||||||
switch (g->target.vectorWidth) {
|
switch (g->target.vectorWidth) {
|
||||||
case 4:
|
case 4:
|
||||||
AddBitcodeToModule(builtins_bitcode_sse2, builtins_bitcode_sse2_length,
|
AddBitcodeToModule(builtins_bitcode_sse2, builtins_bitcode_sse2_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
AddBitcodeToModule(builtins_bitcode_sse2_x2, builtins_bitcode_sse2_x2_length,
|
AddBitcodeToModule(builtins_bitcode_sse2_x2, builtins_bitcode_sse2_x2_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -810,14 +810,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
|||||||
extern unsigned char builtins_bitcode_sse4_x2[];
|
extern unsigned char builtins_bitcode_sse4_x2[];
|
||||||
extern int builtins_bitcode_sse4_x2_length;
|
extern int builtins_bitcode_sse4_x2_length;
|
||||||
switch (g->target.vectorWidth) {
|
switch (g->target.vectorWidth) {
|
||||||
case 4:
|
case 4:
|
||||||
AddBitcodeToModule(builtins_bitcode_sse4,
|
AddBitcodeToModule(builtins_bitcode_sse4,
|
||||||
builtins_bitcode_sse4_length,
|
builtins_bitcode_sse4_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
AddBitcodeToModule(builtins_bitcode_sse4_x2,
|
AddBitcodeToModule(builtins_bitcode_sse4_x2,
|
||||||
builtins_bitcode_sse4_x2_length,
|
builtins_bitcode_sse4_x2_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -829,14 +829,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
|||||||
case 8:
|
case 8:
|
||||||
extern unsigned char builtins_bitcode_avx1[];
|
extern unsigned char builtins_bitcode_avx1[];
|
||||||
extern int builtins_bitcode_avx1_length;
|
extern int builtins_bitcode_avx1_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_avx1,
|
AddBitcodeToModule(builtins_bitcode_avx1,
|
||||||
builtins_bitcode_avx1_length,
|
builtins_bitcode_avx1_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
extern unsigned char builtins_bitcode_avx1_x2[];
|
extern unsigned char builtins_bitcode_avx1_x2[];
|
||||||
extern int builtins_bitcode_avx1_x2_length;
|
extern int builtins_bitcode_avx1_x2_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_avx1_x2,
|
AddBitcodeToModule(builtins_bitcode_avx1_x2,
|
||||||
builtins_bitcode_avx1_x2_length,
|
builtins_bitcode_avx1_x2_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
@@ -849,14 +849,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
|||||||
case 8:
|
case 8:
|
||||||
extern unsigned char builtins_bitcode_avx11[];
|
extern unsigned char builtins_bitcode_avx11[];
|
||||||
extern int builtins_bitcode_avx11_length;
|
extern int builtins_bitcode_avx11_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_avx11,
|
AddBitcodeToModule(builtins_bitcode_avx11,
|
||||||
builtins_bitcode_avx11_length,
|
builtins_bitcode_avx11_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
extern unsigned char builtins_bitcode_avx11_x2[];
|
extern unsigned char builtins_bitcode_avx11_x2[];
|
||||||
extern int builtins_bitcode_avx11_x2_length;
|
extern int builtins_bitcode_avx11_x2_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_avx11_x2,
|
AddBitcodeToModule(builtins_bitcode_avx11_x2,
|
||||||
builtins_bitcode_avx11_x2_length,
|
builtins_bitcode_avx11_x2_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
@@ -869,14 +869,14 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
|||||||
case 8:
|
case 8:
|
||||||
extern unsigned char builtins_bitcode_avx2[];
|
extern unsigned char builtins_bitcode_avx2[];
|
||||||
extern int builtins_bitcode_avx2_length;
|
extern int builtins_bitcode_avx2_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_avx2,
|
AddBitcodeToModule(builtins_bitcode_avx2,
|
||||||
builtins_bitcode_avx2_length,
|
builtins_bitcode_avx2_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
extern unsigned char builtins_bitcode_avx2_x2[];
|
extern unsigned char builtins_bitcode_avx2_x2[];
|
||||||
extern int builtins_bitcode_avx2_x2_length;
|
extern int builtins_bitcode_avx2_x2_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_avx2_x2,
|
AddBitcodeToModule(builtins_bitcode_avx2_x2,
|
||||||
builtins_bitcode_avx2_x2_length,
|
builtins_bitcode_avx2_x2_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
@@ -889,43 +889,43 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
|||||||
case 4:
|
case 4:
|
||||||
extern unsigned char builtins_bitcode_generic_4[];
|
extern unsigned char builtins_bitcode_generic_4[];
|
||||||
extern int builtins_bitcode_generic_4_length;
|
extern int builtins_bitcode_generic_4_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_generic_4,
|
AddBitcodeToModule(builtins_bitcode_generic_4,
|
||||||
builtins_bitcode_generic_4_length,
|
builtins_bitcode_generic_4_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
extern unsigned char builtins_bitcode_generic_8[];
|
extern unsigned char builtins_bitcode_generic_8[];
|
||||||
extern int builtins_bitcode_generic_8_length;
|
extern int builtins_bitcode_generic_8_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_generic_8,
|
AddBitcodeToModule(builtins_bitcode_generic_8,
|
||||||
builtins_bitcode_generic_8_length,
|
builtins_bitcode_generic_8_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
extern unsigned char builtins_bitcode_generic_16[];
|
extern unsigned char builtins_bitcode_generic_16[];
|
||||||
extern int builtins_bitcode_generic_16_length;
|
extern int builtins_bitcode_generic_16_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_generic_16,
|
AddBitcodeToModule(builtins_bitcode_generic_16,
|
||||||
builtins_bitcode_generic_16_length,
|
builtins_bitcode_generic_16_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
extern unsigned char builtins_bitcode_generic_32[];
|
extern unsigned char builtins_bitcode_generic_32[];
|
||||||
extern int builtins_bitcode_generic_32_length;
|
extern int builtins_bitcode_generic_32_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_generic_32,
|
AddBitcodeToModule(builtins_bitcode_generic_32,
|
||||||
builtins_bitcode_generic_32_length,
|
builtins_bitcode_generic_32_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
case 64:
|
case 64:
|
||||||
extern unsigned char builtins_bitcode_generic_64[];
|
extern unsigned char builtins_bitcode_generic_64[];
|
||||||
extern int builtins_bitcode_generic_64_length;
|
extern int builtins_bitcode_generic_64_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_generic_64,
|
AddBitcodeToModule(builtins_bitcode_generic_64,
|
||||||
builtins_bitcode_generic_64_length,
|
builtins_bitcode_generic_64_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
extern unsigned char builtins_bitcode_generic_1[];
|
extern unsigned char builtins_bitcode_generic_1[];
|
||||||
extern int builtins_bitcode_generic_1_length;
|
extern int builtins_bitcode_generic_1_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_generic_1,
|
AddBitcodeToModule(builtins_bitcode_generic_1,
|
||||||
builtins_bitcode_generic_1_length,
|
builtins_bitcode_generic_1_length,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -947,7 +947,7 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
|||||||
lDefineConstantInt("__math_lib", (int)g->mathLib, module, symbolTable);
|
lDefineConstantInt("__math_lib", (int)g->mathLib, module, symbolTable);
|
||||||
lDefineConstantInt("__math_lib_ispc", (int)Globals::Math_ISPC, module,
|
lDefineConstantInt("__math_lib_ispc", (int)Globals::Math_ISPC, module,
|
||||||
symbolTable);
|
symbolTable);
|
||||||
lDefineConstantInt("__math_lib_ispc_fast", (int)Globals::Math_ISPCFast,
|
lDefineConstantInt("__math_lib_ispc_fast", (int)Globals::Math_ISPCFast,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
lDefineConstantInt("__math_lib_svml", (int)Globals::Math_SVML, module,
|
lDefineConstantInt("__math_lib_svml", (int)Globals::Math_SVML, module,
|
||||||
symbolTable);
|
symbolTable);
|
||||||
@@ -956,9 +956,9 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
|
|||||||
lDefineConstantIntFunc("__fast_masked_vload", (int)g->opt.fastMaskedVload,
|
lDefineConstantIntFunc("__fast_masked_vload", (int)g->opt.fastMaskedVload,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
|
|
||||||
lDefineConstantInt("__have_native_half", g->target.hasHalf, module,
|
lDefineConstantInt("__have_native_half", g->target.hasHalf, module,
|
||||||
symbolTable);
|
symbolTable);
|
||||||
lDefineConstantInt("__have_native_rand", g->target.hasRand, module,
|
lDefineConstantInt("__have_native_rand", g->target.hasRand, module,
|
||||||
symbolTable);
|
symbolTable);
|
||||||
lDefineConstantInt("__have_native_transcendentals", g->target.hasTranscendentals,
|
lDefineConstantInt("__have_native_transcendentals", g->target.hasTranscendentals,
|
||||||
module, symbolTable);
|
module, symbolTable);
|
||||||
|
|||||||
@@ -28,11 +28,11 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file builtins.h
|
/** @file builtins.h
|
||||||
@brief Declarations of functions related to builtins and the
|
@brief Declarations of functions related to builtins and the
|
||||||
standard library
|
standard library
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file builtins-c.c
|
/** @file builtins-c.c
|
||||||
@@ -101,12 +101,12 @@ typedef int Bool;
|
|||||||
|
|
||||||
@param format Print format string
|
@param format Print format string
|
||||||
@param types Encoded types of the values being printed.
|
@param types Encoded types of the values being printed.
|
||||||
(See lEncodeType()).
|
(See lEncodeType()).
|
||||||
@param width Vector width of the compilation target
|
@param width Vector width of the compilation target
|
||||||
@param mask Current lane mask when the print statemnt is called
|
@param mask Current lane mask when the print statemnt is called
|
||||||
@param args Array of pointers to the values to be printed
|
@param args Array of pointers to the values to be printed
|
||||||
*/
|
*/
|
||||||
void __do_print(const char *format, const char *types, int width, uint64_t mask,
|
void __do_print(const char *format, const char *types, int width, uint64_t mask,
|
||||||
void **args) {
|
void **args) {
|
||||||
char printString[PRINT_BUF_SIZE+1]; // +1 for trailing NUL
|
char printString[PRINT_BUF_SIZE+1]; // +1 for trailing NUL
|
||||||
char *bufp = &printString[0];
|
char *bufp = &printString[0];
|
||||||
|
|||||||
126
cbackend.cpp
126
cbackend.cpp
@@ -119,12 +119,12 @@ namespace {
|
|||||||
// objects, we keep several helper maps.
|
// objects, we keep several helper maps.
|
||||||
llvm::DenseSet<const llvm::Value*> VisitedConstants;
|
llvm::DenseSet<const llvm::Value*> VisitedConstants;
|
||||||
llvm::DenseSet<llvm::Type*> VisitedTypes;
|
llvm::DenseSet<llvm::Type*> VisitedTypes;
|
||||||
|
|
||||||
std::vector<llvm::ArrayType*> &ArrayTypes;
|
std::vector<llvm::ArrayType*> &ArrayTypes;
|
||||||
public:
|
public:
|
||||||
TypeFinder(std::vector<llvm::ArrayType*> &t)
|
TypeFinder(std::vector<llvm::ArrayType*> &t)
|
||||||
: ArrayTypes(t) {}
|
: ArrayTypes(t) {}
|
||||||
|
|
||||||
void run(const llvm::Module &M) {
|
void run(const llvm::Module &M) {
|
||||||
// Get types from global variables.
|
// Get types from global variables.
|
||||||
for (llvm::Module::const_global_iterator I = M.global_begin(),
|
for (llvm::Module::const_global_iterator I = M.global_begin(),
|
||||||
@@ -133,7 +133,7 @@ namespace {
|
|||||||
if (I->hasInitializer())
|
if (I->hasInitializer())
|
||||||
incorporateValue(I->getInitializer());
|
incorporateValue(I->getInitializer());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get types from aliases.
|
// Get types from aliases.
|
||||||
for (llvm::Module::const_alias_iterator I = M.alias_begin(),
|
for (llvm::Module::const_alias_iterator I = M.alias_begin(),
|
||||||
E = M.alias_end(); I != E; ++I) {
|
E = M.alias_end(); I != E; ++I) {
|
||||||
@@ -141,13 +141,13 @@ namespace {
|
|||||||
if (const llvm::Value *Aliasee = I->getAliasee())
|
if (const llvm::Value *Aliasee = I->getAliasee())
|
||||||
incorporateValue(Aliasee);
|
incorporateValue(Aliasee);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::SmallVector<std::pair<unsigned, llvm::MDNode*>, 4> MDForInst;
|
llvm::SmallVector<std::pair<unsigned, llvm::MDNode*>, 4> MDForInst;
|
||||||
|
|
||||||
// Get types from functions.
|
// Get types from functions.
|
||||||
for (llvm::Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
|
for (llvm::Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
|
||||||
incorporateType(FI->getType());
|
incorporateType(FI->getType());
|
||||||
|
|
||||||
for (llvm::Function::const_iterator BB = FI->begin(), E = FI->end();
|
for (llvm::Function::const_iterator BB = FI->begin(), E = FI->end();
|
||||||
BB != E;++BB)
|
BB != E;++BB)
|
||||||
for (llvm::BasicBlock::const_iterator II = BB->begin(),
|
for (llvm::BasicBlock::const_iterator II = BB->begin(),
|
||||||
@@ -158,13 +158,13 @@ namespace {
|
|||||||
// Seems like there ought to be better way to do what we
|
// Seems like there ought to be better way to do what we
|
||||||
// want here. For now, punt on SwitchInsts.
|
// want here. For now, punt on SwitchInsts.
|
||||||
if (llvm::isa<llvm::SwitchInst>(&I)) continue;
|
if (llvm::isa<llvm::SwitchInst>(&I)) continue;
|
||||||
|
|
||||||
// Incorporate the type of the instruction and all its operands.
|
// Incorporate the type of the instruction and all its operands.
|
||||||
incorporateType(I.getType());
|
incorporateType(I.getType());
|
||||||
for (llvm::User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
|
for (llvm::User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
|
||||||
OI != OE; ++OI)
|
OI != OE; ++OI)
|
||||||
incorporateValue(*OI);
|
incorporateValue(*OI);
|
||||||
|
|
||||||
// Incorporate types hiding in metadata.
|
// Incorporate types hiding in metadata.
|
||||||
I.getAllMetadataOtherThanDebugLoc(MDForInst);
|
I.getAllMetadataOtherThanDebugLoc(MDForInst);
|
||||||
for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
|
for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
|
||||||
@@ -172,7 +172,7 @@ namespace {
|
|||||||
MDForInst.clear();
|
MDForInst.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(),
|
for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(),
|
||||||
E = M.named_metadata_end(); I != E; ++I) {
|
E = M.named_metadata_end(); I != E; ++I) {
|
||||||
const llvm::NamedMDNode *NMD = I;
|
const llvm::NamedMDNode *NMD = I;
|
||||||
@@ -180,7 +180,7 @@ namespace {
|
|||||||
incorporateMDNode(NMD->getOperand(i));
|
incorporateMDNode(NMD->getOperand(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void incorporateType(llvm::Type *Ty) {
|
void incorporateType(llvm::Type *Ty) {
|
||||||
// Check to see if we're already visited this type.
|
// Check to see if we're already visited this type.
|
||||||
@@ -189,13 +189,13 @@ namespace {
|
|||||||
|
|
||||||
if (llvm::ArrayType *ATy = llvm::dyn_cast<llvm::ArrayType>(Ty))
|
if (llvm::ArrayType *ATy = llvm::dyn_cast<llvm::ArrayType>(Ty))
|
||||||
ArrayTypes.push_back(ATy);
|
ArrayTypes.push_back(ATy);
|
||||||
|
|
||||||
// Recursively walk all contained types.
|
// Recursively walk all contained types.
|
||||||
for (llvm::Type::subtype_iterator I = Ty->subtype_begin(),
|
for (llvm::Type::subtype_iterator I = Ty->subtype_begin(),
|
||||||
E = Ty->subtype_end(); I != E; ++I)
|
E = Ty->subtype_end(); I != E; ++I)
|
||||||
incorporateType(*I);
|
incorporateType(*I);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// incorporateValue - This method is used to walk operand lists finding
|
/// incorporateValue - This method is used to walk operand lists finding
|
||||||
/// types hiding in constant expressions and other operands that won't be
|
/// types hiding in constant expressions and other operands that won't be
|
||||||
/// walked in other ways. GlobalValues, basic blocks, instructions, and
|
/// walked in other ways. GlobalValues, basic blocks, instructions, and
|
||||||
@@ -204,27 +204,27 @@ namespace {
|
|||||||
if (const llvm::MDNode *M = llvm::dyn_cast<llvm::MDNode>(V))
|
if (const llvm::MDNode *M = llvm::dyn_cast<llvm::MDNode>(V))
|
||||||
return incorporateMDNode(M);
|
return incorporateMDNode(M);
|
||||||
if (!llvm::isa<llvm::Constant>(V) || llvm::isa<llvm::GlobalValue>(V)) return;
|
if (!llvm::isa<llvm::Constant>(V) || llvm::isa<llvm::GlobalValue>(V)) return;
|
||||||
|
|
||||||
// Already visited?
|
// Already visited?
|
||||||
if (!VisitedConstants.insert(V).second)
|
if (!VisitedConstants.insert(V).second)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check this type.
|
// Check this type.
|
||||||
incorporateType(V->getType());
|
incorporateType(V->getType());
|
||||||
|
|
||||||
// Look in operands for types.
|
// Look in operands for types.
|
||||||
const llvm::User *U = llvm::cast<llvm::User>(V);
|
const llvm::User *U = llvm::cast<llvm::User>(V);
|
||||||
for (llvm::Constant::const_op_iterator I = U->op_begin(),
|
for (llvm::Constant::const_op_iterator I = U->op_begin(),
|
||||||
E = U->op_end(); I != E;++I)
|
E = U->op_end(); I != E;++I)
|
||||||
incorporateValue(*I);
|
incorporateValue(*I);
|
||||||
}
|
}
|
||||||
|
|
||||||
void incorporateMDNode(const llvm::MDNode *V) {
|
void incorporateMDNode(const llvm::MDNode *V) {
|
||||||
|
|
||||||
// Already visited?
|
// Already visited?
|
||||||
if (!VisitedConstants.insert(V).second)
|
if (!VisitedConstants.insert(V).second)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Look in operands for types.
|
// Look in operands for types.
|
||||||
for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i)
|
||||||
if (llvm::Value *Op = V->getOperand(i))
|
if (llvm::Value *Op = V->getOperand(i))
|
||||||
@@ -266,7 +266,7 @@ namespace {
|
|||||||
// TargetData have generally similar interfaces...
|
// TargetData have generally similar interfaces...
|
||||||
const llvm::DataLayout* TD;
|
const llvm::DataLayout* TD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::map<const llvm::ConstantFP *, unsigned> FPConstantMap;
|
std::map<const llvm::ConstantFP *, unsigned> FPConstantMap;
|
||||||
std::map<const llvm::ConstantDataVector *, unsigned> VectorConstantMap;
|
std::map<const llvm::ConstantDataVector *, unsigned> VectorConstantMap;
|
||||||
unsigned VectorConstantIndex;
|
unsigned VectorConstantIndex;
|
||||||
@@ -276,7 +276,7 @@ namespace {
|
|||||||
unsigned OpaqueCounter;
|
unsigned OpaqueCounter;
|
||||||
llvm::DenseMap<const llvm::Value*, unsigned> AnonValueNumbers;
|
llvm::DenseMap<const llvm::Value*, unsigned> AnonValueNumbers;
|
||||||
unsigned NextAnonValueNumber;
|
unsigned NextAnonValueNumber;
|
||||||
|
|
||||||
std::string includeName;
|
std::string includeName;
|
||||||
int vectorWidth;
|
int vectorWidth;
|
||||||
|
|
||||||
@@ -291,7 +291,7 @@ namespace {
|
|||||||
int vecwidth)
|
int vecwidth)
|
||||||
: FunctionPass(ID), Out(o), IL(0), /* Mang(0), */ LI(0),
|
: FunctionPass(ID), Out(o), IL(0), /* Mang(0), */ LI(0),
|
||||||
TheModule(0), TAsm(0), MRI(0), MOFI(0), TCtx(0), TD(0),
|
TheModule(0), TAsm(0), MRI(0), MOFI(0), TCtx(0), TD(0),
|
||||||
OpaqueCounter(0), NextAnonValueNumber(0),
|
OpaqueCounter(0), NextAnonValueNumber(0),
|
||||||
includeName(incname ? incname : "generic_defs.h"),
|
includeName(incname ? incname : "generic_defs.h"),
|
||||||
vectorWidth(vecwidth) {
|
vectorWidth(vecwidth) {
|
||||||
initializeLoopInfoPass(*llvm::PassRegistry::getPassRegistry());
|
initializeLoopInfoPass(*llvm::PassRegistry::getPassRegistry());
|
||||||
@@ -372,7 +372,7 @@ namespace {
|
|||||||
|
|
||||||
std::string getStructName(llvm::StructType *ST);
|
std::string getStructName(llvm::StructType *ST);
|
||||||
std::string getArrayName(llvm::ArrayType *AT);
|
std::string getArrayName(llvm::ArrayType *AT);
|
||||||
|
|
||||||
/// writeOperandDeref - Print the result of dereferencing the specified
|
/// writeOperandDeref - Print the result of dereferencing the specified
|
||||||
/// operand with '*'. This is equivalent to printing '*' then using
|
/// operand with '*'. This is equivalent to printing '*' then using
|
||||||
/// writeOperand, but avoids excess syntax in some cases.
|
/// writeOperand, but avoids excess syntax in some cases.
|
||||||
@@ -399,7 +399,7 @@ namespace {
|
|||||||
|
|
||||||
private :
|
private :
|
||||||
void lowerIntrinsics(llvm::Function &F);
|
void lowerIntrinsics(llvm::Function &F);
|
||||||
/// Prints the definition of the intrinsic function F. Supports the
|
/// Prints the definition of the intrinsic function F. Supports the
|
||||||
/// intrinsics which need to be explicitly defined in the CBackend.
|
/// intrinsics which need to be explicitly defined in the CBackend.
|
||||||
void printIntrinsicDefinition(const llvm::Function &F, llvm::raw_ostream &Out);
|
void printIntrinsicDefinition(const llvm::Function &F, llvm::raw_ostream &Out);
|
||||||
|
|
||||||
@@ -573,7 +573,7 @@ static std::string CBEMangle(const std::string &S) {
|
|||||||
std::string CWriter::getStructName(llvm::StructType *ST) {
|
std::string CWriter::getStructName(llvm::StructType *ST) {
|
||||||
if (!ST->isLiteral() && !ST->getName().empty())
|
if (!ST->isLiteral() && !ST->getName().empty())
|
||||||
return CBEMangle("l_"+ST->getName().str());
|
return CBEMangle("l_"+ST->getName().str());
|
||||||
|
|
||||||
return "l_unnamed_" + llvm::utostr(UnnamedStructIDs[ST]);
|
return "l_unnamed_" + llvm::utostr(UnnamedStructIDs[ST]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -694,19 +694,19 @@ CWriter::printSimpleType(llvm::raw_ostream &Out, llvm::Type *Ty, bool isSigned,
|
|||||||
assert(eltTy->isIntegerTy());
|
assert(eltTy->isIntegerTy());
|
||||||
switch (eltTy->getPrimitiveSizeInBits()) {
|
switch (eltTy->getPrimitiveSizeInBits()) {
|
||||||
case 1:
|
case 1:
|
||||||
suffix = "i1";
|
suffix = "i1";
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
suffix = "i8";
|
suffix = "i8";
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
suffix = "i16";
|
suffix = "i16";
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
suffix = "i32";
|
suffix = "i32";
|
||||||
break;
|
break;
|
||||||
case 64:
|
case 64:
|
||||||
suffix = "i64";
|
suffix = "i64";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
llvm::report_fatal_error("Only integer types of size 8/16/32/64 are "
|
llvm::report_fatal_error("Only integer types of size 8/16/32/64 are "
|
||||||
@@ -714,7 +714,7 @@ CWriter::printSimpleType(llvm::raw_ostream &Out, llvm::Type *Ty, bool isSigned,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Out << "__vec" << VTy->getNumElements() << "_" << suffix << " " <<
|
return Out << "__vec" << VTy->getNumElements() << "_" << suffix << " " <<
|
||||||
NameSoFar;
|
NameSoFar;
|
||||||
#else
|
#else
|
||||||
return printSimpleType(Out, VTy->getElementType(), isSigned,
|
return printSimpleType(Out, VTy->getElementType(), isSigned,
|
||||||
@@ -736,7 +736,7 @@ CWriter::printSimpleType(llvm::raw_ostream &Out, llvm::Type *Ty, bool isSigned,
|
|||||||
//
|
//
|
||||||
llvm::raw_ostream &CWriter::printType(llvm::raw_ostream &Out, llvm::Type *Ty,
|
llvm::raw_ostream &CWriter::printType(llvm::raw_ostream &Out, llvm::Type *Ty,
|
||||||
bool isSigned, const std::string &NameSoFar,
|
bool isSigned, const std::string &NameSoFar,
|
||||||
bool IgnoreName,
|
bool IgnoreName,
|
||||||
#if defined(LLVM_3_1) || defined(LLVM_3_2)
|
#if defined(LLVM_3_1) || defined(LLVM_3_2)
|
||||||
const llvm::AttrListPtr &PAL
|
const llvm::AttrListPtr &PAL
|
||||||
#else
|
#else
|
||||||
@@ -803,11 +803,11 @@ llvm::raw_ostream &CWriter::printType(llvm::raw_ostream &Out, llvm::Type *Ty,
|
|||||||
}
|
}
|
||||||
case llvm::Type::StructTyID: {
|
case llvm::Type::StructTyID: {
|
||||||
llvm::StructType *STy = llvm::cast<llvm::StructType>(Ty);
|
llvm::StructType *STy = llvm::cast<llvm::StructType>(Ty);
|
||||||
|
|
||||||
// Check to see if the type is named.
|
// Check to see if the type is named.
|
||||||
if (!IgnoreName)
|
if (!IgnoreName)
|
||||||
return Out << getStructName(STy) << ' ' << NameSoFar;
|
return Out << getStructName(STy) << ' ' << NameSoFar;
|
||||||
|
|
||||||
Out << "struct " << NameSoFar << " {\n";
|
Out << "struct " << NameSoFar << " {\n";
|
||||||
|
|
||||||
// print initialization func
|
// print initialization func
|
||||||
@@ -930,13 +930,13 @@ void CWriter::printConstantDataSequential(llvm::ConstantDataSequential *CDS,
|
|||||||
Out << '\"';
|
Out << '\"';
|
||||||
// Keep track of whether the last number was a hexadecimal escape.
|
// Keep track of whether the last number was a hexadecimal escape.
|
||||||
bool LastWasHex = false;
|
bool LastWasHex = false;
|
||||||
|
|
||||||
llvm::StringRef Bytes = CDS->getAsCString();
|
llvm::StringRef Bytes = CDS->getAsCString();
|
||||||
|
|
||||||
// Do not include the last character, which we know is null
|
// Do not include the last character, which we know is null
|
||||||
for (unsigned i = 0, e = Bytes.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Bytes.size(); i != e; ++i) {
|
||||||
unsigned char C = Bytes[i];
|
unsigned char C = Bytes[i];
|
||||||
|
|
||||||
// Print it out literally if it is a printable character. The only thing
|
// Print it out literally if it is a printable character. The only thing
|
||||||
// to be careful about is when the last letter output was a hex escape
|
// to be careful about is when the last letter output was a hex escape
|
||||||
// code, in which case we have to be careful not to print out hex digits
|
// code, in which case we have to be careful not to print out hex digits
|
||||||
@@ -1143,8 +1143,8 @@ bool CWriter::printCast(unsigned opc, llvm::Type *SrcTy, llvm::Type *DstTy) {
|
|||||||
|
|
||||||
|
|
||||||
/** Construct the name of a function with the given base and returning a
|
/** Construct the name of a function with the given base and returning a
|
||||||
vector of a given type, of the specified idth. For example, if base
|
vector of a given type, of the specified idth. For example, if base
|
||||||
is "foo" and matchType is i32 and width is 16, this will return the
|
is "foo" and matchType is i32 and width is 16, this will return the
|
||||||
string "__foo_i32<__vec16_i32>".
|
string "__foo_i32<__vec16_i32>".
|
||||||
*/
|
*/
|
||||||
static const char *
|
static const char *
|
||||||
@@ -1492,7 +1492,7 @@ void CWriter::printConstant(llvm::Constant *CPV, bool Static) {
|
|||||||
}
|
}
|
||||||
if (llvm::ConstantArray *CA = llvm::dyn_cast<llvm::ConstantArray>(CPV)) {
|
if (llvm::ConstantArray *CA = llvm::dyn_cast<llvm::ConstantArray>(CPV)) {
|
||||||
printConstantArray(CA, Static);
|
printConstantArray(CA, Static);
|
||||||
} else if (llvm::ConstantDataSequential *CDS =
|
} else if (llvm::ConstantDataSequential *CDS =
|
||||||
llvm::dyn_cast<llvm::ConstantDataSequential>(CPV)) {
|
llvm::dyn_cast<llvm::ConstantDataSequential>(CPV)) {
|
||||||
printConstantDataSequential(CDS, Static);
|
printConstantDataSequential(CDS, Static);
|
||||||
} else {
|
} else {
|
||||||
@@ -1584,7 +1584,7 @@ void CWriter::printConstant(llvm::Constant *CPV, bool Static) {
|
|||||||
llvm::report_fatal_error("Unexpected vector type");
|
llvm::report_fatal_error("Unexpected vector type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case llvm::Type::StructTyID:
|
case llvm::Type::StructTyID:
|
||||||
@@ -2658,7 +2658,7 @@ void CWriter::printModuleTypes() {
|
|||||||
Out << "/* Structure and array forward declarations */\n";
|
Out << "/* Structure and array forward declarations */\n";
|
||||||
|
|
||||||
unsigned NextTypeID = 0;
|
unsigned NextTypeID = 0;
|
||||||
|
|
||||||
// If any of them are missing names, add a unique ID to UnnamedStructIDs.
|
// If any of them are missing names, add a unique ID to UnnamedStructIDs.
|
||||||
// Print out forward declarations for structure types.
|
// Print out forward declarations for structure types.
|
||||||
for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) {
|
for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) {
|
||||||
@@ -2718,7 +2718,7 @@ void CWriter::printContainedStructs(llvm::Type *Ty,
|
|||||||
if (llvm::StructType *ST = llvm::dyn_cast<llvm::StructType>(Ty)) {
|
if (llvm::StructType *ST = llvm::dyn_cast<llvm::StructType>(Ty)) {
|
||||||
// Check to see if we have already printed this struct.
|
// Check to see if we have already printed this struct.
|
||||||
if (!Printed.insert(Ty)) return;
|
if (!Printed.insert(Ty)) return;
|
||||||
|
|
||||||
// Print structure type out.
|
// Print structure type out.
|
||||||
printType(Out, ST, false, getStructName(ST), true);
|
printType(Out, ST, false, getStructName(ST), true);
|
||||||
Out << ";\n\n";
|
Out << ";\n\n";
|
||||||
@@ -3623,8 +3623,8 @@ void CWriter::printIntrinsicDefinition(const llvm::Function &F, llvm::raw_ostrea
|
|||||||
Out << " r.field1 = (r.field0 < a);\n";
|
Out << " r.field1 = (r.field0 < a);\n";
|
||||||
Out << " return r;\n}\n";
|
Out << " return r;\n}\n";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case llvm::Intrinsic::sadd_with_overflow:
|
case llvm::Intrinsic::sadd_with_overflow:
|
||||||
// static inline Rty sadd_ixx(ixx a, ixx b) {
|
// static inline Rty sadd_ixx(ixx a, ixx b) {
|
||||||
// Rty r;
|
// Rty r;
|
||||||
// r.field1 = (b > 0 && a > XX_MAX - b) ||
|
// r.field1 = (b > 0 && a > XX_MAX - b) ||
|
||||||
@@ -3851,10 +3851,10 @@ void CWriter::visitCallInst(llvm::CallInst &I) {
|
|||||||
Out << ')';
|
Out << ')';
|
||||||
}
|
}
|
||||||
// Check if the argument is expected to be passed by value.
|
// Check if the argument is expected to be passed by value.
|
||||||
if (I.paramHasAttr(ArgNo+1,
|
if (I.paramHasAttr(ArgNo+1,
|
||||||
#if defined(LLVM_3_2)
|
#if defined(LLVM_3_2)
|
||||||
llvm::Attributes::ByVal
|
llvm::Attributes::ByVal
|
||||||
#else
|
#else
|
||||||
llvm::Attribute::ByVal
|
llvm::Attribute::ByVal
|
||||||
#endif
|
#endif
|
||||||
))
|
))
|
||||||
@@ -4419,7 +4419,7 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
|||||||
|
|
||||||
restart:
|
restart:
|
||||||
for (llvm::BasicBlock::iterator iter = bb.begin(), e = bb.end(); iter != e; ++iter) {
|
for (llvm::BasicBlock::iterator iter = bb.begin(), e = bb.end(); iter != e; ++iter) {
|
||||||
llvm::InsertElementInst *insertInst =
|
llvm::InsertElementInst *insertInst =
|
||||||
llvm::dyn_cast<llvm::InsertElementInst>(&*iter);
|
llvm::dyn_cast<llvm::InsertElementInst>(&*iter);
|
||||||
if (insertInst == NULL)
|
if (insertInst == NULL)
|
||||||
continue;
|
continue;
|
||||||
@@ -4444,7 +4444,7 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
|||||||
else if (toMatch != insertValue)
|
else if (toMatch != insertValue)
|
||||||
goto not_equal;
|
goto not_equal;
|
||||||
|
|
||||||
insertInst =
|
insertInst =
|
||||||
llvm::dyn_cast<llvm::InsertElementInst>(insertInst->getOperand(0));
|
llvm::dyn_cast<llvm::InsertElementInst>(insertInst->getOperand(0));
|
||||||
}
|
}
|
||||||
assert(toMatch != NULL);
|
assert(toMatch != NULL);
|
||||||
@@ -4458,8 +4458,8 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
|||||||
// Declare the smear function if needed; it takes a single
|
// Declare the smear function if needed; it takes a single
|
||||||
// scalar parameter and returns a vector of the same
|
// scalar parameter and returns a vector of the same
|
||||||
// parameter type.
|
// parameter type.
|
||||||
llvm::Constant *sf =
|
llvm::Constant *sf =
|
||||||
module->getOrInsertFunction(smearFuncName, iter->getType(),
|
module->getOrInsertFunction(smearFuncName, iter->getType(),
|
||||||
matchType, NULL);
|
matchType, NULL);
|
||||||
smearFunc = llvm::dyn_cast<llvm::Function>(sf);
|
smearFunc = llvm::dyn_cast<llvm::Function>(sf);
|
||||||
assert(smearFunc != NULL);
|
assert(smearFunc != NULL);
|
||||||
@@ -4475,7 +4475,7 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
|||||||
assert(smearFunc != NULL);
|
assert(smearFunc != NULL);
|
||||||
llvm::Value *args[1] = { toMatch };
|
llvm::Value *args[1] = { toMatch };
|
||||||
llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[1]);
|
llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[1]);
|
||||||
llvm::Instruction *smearCall =
|
llvm::Instruction *smearCall =
|
||||||
llvm::CallInst::Create(smearFunc, argArray, LLVMGetName(toMatch, "_smear"),
|
llvm::CallInst::Create(smearFunc, argArray, LLVMGetName(toMatch, "_smear"),
|
||||||
(llvm::Instruction *)NULL);
|
(llvm::Instruction *)NULL);
|
||||||
|
|
||||||
@@ -4608,9 +4608,9 @@ AndCmpCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
|||||||
// are the same as the two arguments to the compare we're
|
// are the same as the two arguments to the compare we're
|
||||||
// replacing and the third argument is the mask type.
|
// replacing and the third argument is the mask type.
|
||||||
llvm::Type *cmpOpType = opCmp->getOperand(0)->getType();
|
llvm::Type *cmpOpType = opCmp->getOperand(0)->getType();
|
||||||
llvm::Constant *acf =
|
llvm::Constant *acf =
|
||||||
m->module->getOrInsertFunction(funcName, LLVMTypes::MaskType,
|
m->module->getOrInsertFunction(funcName, LLVMTypes::MaskType,
|
||||||
cmpOpType, cmpOpType,
|
cmpOpType, cmpOpType,
|
||||||
LLVMTypes::MaskType, NULL);
|
LLVMTypes::MaskType, NULL);
|
||||||
andCmpFunc = llvm::dyn_cast<llvm::Function>(acf);
|
andCmpFunc = llvm::dyn_cast<llvm::Function>(acf);
|
||||||
Assert(andCmpFunc != NULL);
|
Assert(andCmpFunc != NULL);
|
||||||
@@ -4625,11 +4625,11 @@ AndCmpCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
|||||||
|
|
||||||
// Set up the function call to the *_and_mask function; the
|
// Set up the function call to the *_and_mask function; the
|
||||||
// mask value passed in is the other operand to the AND.
|
// mask value passed in is the other operand to the AND.
|
||||||
llvm::Value *args[3] = { opCmp->getOperand(0), opCmp->getOperand(1),
|
llvm::Value *args[3] = { opCmp->getOperand(0), opCmp->getOperand(1),
|
||||||
bop->getOperand(i ^ 1) };
|
bop->getOperand(i ^ 1) };
|
||||||
llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[3]);
|
llvm::ArrayRef<llvm::Value *> argArray(&args[0], &args[3]);
|
||||||
llvm::Instruction *cmpCall =
|
llvm::Instruction *cmpCall =
|
||||||
llvm::CallInst::Create(andCmpFunc, argArray,
|
llvm::CallInst::Create(andCmpFunc, argArray,
|
||||||
LLVMGetName(bop, "_and_mask"),
|
LLVMGetName(bop, "_and_mask"),
|
||||||
(llvm::Instruction *)NULL);
|
(llvm::Instruction *)NULL);
|
||||||
|
|
||||||
@@ -4656,12 +4656,12 @@ AndCmpCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
|||||||
class MaskOpsCleanupPass : public llvm::BasicBlockPass {
|
class MaskOpsCleanupPass : public llvm::BasicBlockPass {
|
||||||
public:
|
public:
|
||||||
MaskOpsCleanupPass(llvm::Module *m)
|
MaskOpsCleanupPass(llvm::Module *m)
|
||||||
: BasicBlockPass(ID) {
|
: BasicBlockPass(ID) {
|
||||||
llvm::Type *mt = LLVMTypes::MaskType;
|
llvm::Type *mt = LLVMTypes::MaskType;
|
||||||
|
|
||||||
// Declare the __not, __and_not1, and __and_not2 functions that we
|
// Declare the __not, __and_not1, and __and_not2 functions that we
|
||||||
// expect the target to end up providing.
|
// expect the target to end up providing.
|
||||||
notFunc =
|
notFunc =
|
||||||
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__not", mt, mt, NULL));
|
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__not", mt, mt, NULL));
|
||||||
assert(notFunc != NULL);
|
assert(notFunc != NULL);
|
||||||
#if defined(LLVM_3_2)
|
#if defined(LLVM_3_2)
|
||||||
@@ -4672,7 +4672,7 @@ public:
|
|||||||
notFunc->addFnAttr(llvm::Attribute::ReadNone);
|
notFunc->addFnAttr(llvm::Attribute::ReadNone);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
andNotFuncs[0] =
|
andNotFuncs[0] =
|
||||||
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not1", mt, mt, mt,
|
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not1", mt, mt, mt,
|
||||||
NULL));
|
NULL));
|
||||||
assert(andNotFuncs[0] != NULL);
|
assert(andNotFuncs[0] != NULL);
|
||||||
@@ -4683,7 +4683,7 @@ public:
|
|||||||
andNotFuncs[0]->addFnAttr(llvm::Attribute::NoUnwind);
|
andNotFuncs[0]->addFnAttr(llvm::Attribute::NoUnwind);
|
||||||
andNotFuncs[0]->addFnAttr(llvm::Attribute::ReadNone);
|
andNotFuncs[0]->addFnAttr(llvm::Attribute::ReadNone);
|
||||||
#endif
|
#endif
|
||||||
andNotFuncs[1] =
|
andNotFuncs[1] =
|
||||||
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not2", mt, mt, mt,
|
llvm::dyn_cast<llvm::Function>(m->getOrInsertFunction("__and_not2", mt, mt, mt,
|
||||||
NULL));
|
NULL));
|
||||||
assert(andNotFuncs[1] != NULL);
|
assert(andNotFuncs[1] != NULL);
|
||||||
@@ -4711,7 +4711,7 @@ char MaskOpsCleanupPass::ID = 0;
|
|||||||
|
|
||||||
|
|
||||||
/** Returns true if the given value is a compile-time constant vector of
|
/** Returns true if the given value is a compile-time constant vector of
|
||||||
i1s with all elements 'true'.
|
i1s with all elements 'true'.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
lIsAllTrue(llvm::Value *v) {
|
lIsAllTrue(llvm::Value *v) {
|
||||||
@@ -4721,7 +4721,7 @@ lIsAllTrue(llvm::Value *v) {
|
|||||||
(ci = llvm::dyn_cast<llvm::ConstantInt>(cv->getSplatValue())) != NULL &&
|
(ci = llvm::dyn_cast<llvm::ConstantInt>(cv->getSplatValue())) != NULL &&
|
||||||
ci->isOne());
|
ci->isOne());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (llvm::ConstantDataVector *cdv = llvm::dyn_cast<llvm::ConstantDataVector>(v)) {
|
if (llvm::ConstantDataVector *cdv = llvm::dyn_cast<llvm::ConstantDataVector>(v)) {
|
||||||
llvm::ConstantInt *ci;
|
llvm::ConstantInt *ci;
|
||||||
return (cdv->getSplatValue() != NULL &&
|
return (cdv->getSplatValue() != NULL &&
|
||||||
@@ -4770,7 +4770,7 @@ MaskOpsCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
|||||||
// Check for XOR with all-true values
|
// Check for XOR with all-true values
|
||||||
if (lIsAllTrue(bop->getOperand(1))) {
|
if (lIsAllTrue(bop->getOperand(1))) {
|
||||||
llvm::ArrayRef<llvm::Value *> arg(bop->getOperand(0));
|
llvm::ArrayRef<llvm::Value *> arg(bop->getOperand(0));
|
||||||
llvm::CallInst *notCall = llvm::CallInst::Create(notFunc, arg,
|
llvm::CallInst *notCall = llvm::CallInst::Create(notFunc, arg,
|
||||||
bop->getName());
|
bop->getName());
|
||||||
ReplaceInstWithInst(iter, notCall);
|
ReplaceInstWithInst(iter, notCall);
|
||||||
modifiedAny = true;
|
modifiedAny = true;
|
||||||
@@ -4791,7 +4791,7 @@ MaskOpsCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) {
|
|||||||
llvm::ArrayRef<llvm::Value *> argsRef(&args[0], 2);
|
llvm::ArrayRef<llvm::Value *> argsRef(&args[0], 2);
|
||||||
|
|
||||||
// Call the appropriate __and_not* function.
|
// Call the appropriate __and_not* function.
|
||||||
llvm::CallInst *andNotCall =
|
llvm::CallInst *andNotCall =
|
||||||
llvm::CallInst::Create(andNotFuncs[i], argsRef, bop->getName());
|
llvm::CallInst::Create(andNotFuncs[i], argsRef, bop->getName());
|
||||||
|
|
||||||
ReplaceInstWithInst(iter, andNotCall);
|
ReplaceInstWithInst(iter, andNotCall);
|
||||||
|
|||||||
54
ctx.h
54
ctx.h
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file ctx.h
|
/** @file ctx.h
|
||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
@param firstStmtPos Source file position of the first statement in the
|
@param firstStmtPos Source file position of the first statement in the
|
||||||
function
|
function
|
||||||
*/
|
*/
|
||||||
FunctionEmitContext(Function *function, Symbol *funSym,
|
FunctionEmitContext(Function *function, Symbol *funSym,
|
||||||
llvm::Function *llvmFunction,
|
llvm::Function *llvmFunction,
|
||||||
SourcePos firstStmtPos);
|
SourcePos firstStmtPos);
|
||||||
~FunctionEmitContext();
|
~FunctionEmitContext();
|
||||||
@@ -87,9 +87,9 @@ public:
|
|||||||
/** @name Current basic block management
|
/** @name Current basic block management
|
||||||
@{
|
@{
|
||||||
*/
|
*/
|
||||||
/** Returns the current basic block pointer */
|
/** Returns the current basic block pointer */
|
||||||
llvm::BasicBlock *GetCurrentBasicBlock();
|
llvm::BasicBlock *GetCurrentBasicBlock();
|
||||||
|
|
||||||
/** Set the given llvm::BasicBlock to be the basic block to emit
|
/** Set the given llvm::BasicBlock to be the basic block to emit
|
||||||
forthcoming instructions into. */
|
forthcoming instructions into. */
|
||||||
void SetCurrentBasicBlock(llvm::BasicBlock *bblock);
|
void SetCurrentBasicBlock(llvm::BasicBlock *bblock);
|
||||||
@@ -97,7 +97,7 @@ public:
|
|||||||
/** @name Mask management
|
/** @name Mask management
|
||||||
@{
|
@{
|
||||||
*/
|
*/
|
||||||
/** Returns the mask value at entry to the current function. */
|
/** Returns the mask value at entry to the current function. */
|
||||||
llvm::Value *GetFunctionMask();
|
llvm::Value *GetFunctionMask();
|
||||||
|
|
||||||
/** Returns the mask value corresponding to "varying" control flow
|
/** Returns the mask value corresponding to "varying" control flow
|
||||||
@@ -106,7 +106,7 @@ public:
|
|||||||
llvm::Value *GetInternalMask();
|
llvm::Value *GetInternalMask();
|
||||||
|
|
||||||
/** Returns the complete current mask value--i.e. the logical AND of
|
/** Returns the complete current mask value--i.e. the logical AND of
|
||||||
the function entry mask and the internal mask. */
|
the function entry mask and the internal mask. */
|
||||||
llvm::Value *GetFullMask();
|
llvm::Value *GetFullMask();
|
||||||
|
|
||||||
/** Returns a pointer to storage in memory that stores the current full
|
/** Returns a pointer to storage in memory that stores the current full
|
||||||
@@ -159,7 +159,7 @@ public:
|
|||||||
'continue' statements should jump to (if all running lanes want to
|
'continue' statements should jump to (if all running lanes want to
|
||||||
break or continue), uniformControlFlow indicates whether the loop
|
break or continue), uniformControlFlow indicates whether the loop
|
||||||
condition is 'uniform'. */
|
condition is 'uniform'. */
|
||||||
void StartLoop(llvm::BasicBlock *breakTarget, llvm::BasicBlock *continueTarget,
|
void StartLoop(llvm::BasicBlock *breakTarget, llvm::BasicBlock *continueTarget,
|
||||||
bool uniformControlFlow);
|
bool uniformControlFlow);
|
||||||
|
|
||||||
/** Informs FunctionEmitContext of the value of the mask at the start
|
/** Informs FunctionEmitContext of the value of the mask at the start
|
||||||
@@ -213,8 +213,8 @@ public:
|
|||||||
@param caseBlocks vector that stores the mapping from label values
|
@param caseBlocks vector that stores the mapping from label values
|
||||||
after "case" statements to basic blocks corresponding
|
after "case" statements to basic blocks corresponding
|
||||||
to the "case" labels.
|
to the "case" labels.
|
||||||
@param nextBlocks For each basic block for a "case" or "default"
|
@param nextBlocks For each basic block for a "case" or "default"
|
||||||
label, this gives the basic block for the
|
label, this gives the basic block for the
|
||||||
immediately-following "case" or "default" label (or
|
immediately-following "case" or "default" label (or
|
||||||
the basic block after the "switch" statement for the
|
the basic block after the "switch" statement for the
|
||||||
last label.)
|
last label.)
|
||||||
@@ -272,7 +272,7 @@ public:
|
|||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** @name Small helper/utility routines
|
/** @name Small helper/utility routines
|
||||||
@{
|
@{
|
||||||
*/
|
*/
|
||||||
/** Given a boolean mask value of type LLVMTypes::MaskType, return an
|
/** Given a boolean mask value of type LLVMTypes::MaskType, return an
|
||||||
i1 value that indicates if any of the mask lanes are on. */
|
i1 value that indicates if any of the mask lanes are on. */
|
||||||
@@ -332,7 +332,7 @@ public:
|
|||||||
llvm::Instruction for convenience; in calling code we often have
|
llvm::Instruction for convenience; in calling code we often have
|
||||||
Instructions stored using Value pointers; the code here returns
|
Instructions stored using Value pointers; the code here returns
|
||||||
silently if it's not actually given an instruction. */
|
silently if it's not actually given an instruction. */
|
||||||
void AddDebugPos(llvm::Value *instruction, const SourcePos *pos = NULL,
|
void AddDebugPos(llvm::Value *instruction, const SourcePos *pos = NULL,
|
||||||
llvm::DIScope *scope = NULL);
|
llvm::DIScope *scope = NULL);
|
||||||
|
|
||||||
/** Inform the debugging information generation code that a new scope
|
/** Inform the debugging information generation code that a new scope
|
||||||
@@ -361,7 +361,7 @@ public:
|
|||||||
instructions. See the LLVM assembly language reference manual
|
instructions. See the LLVM assembly language reference manual
|
||||||
(http://llvm.org/docs/LangRef.html) and the LLVM doxygen documentaion
|
(http://llvm.org/docs/LangRef.html) and the LLVM doxygen documentaion
|
||||||
(http://llvm.org/doxygen) for more information. Here we will only
|
(http://llvm.org/doxygen) for more information. Here we will only
|
||||||
document significant generalizations to the functionality of the
|
document significant generalizations to the functionality of the
|
||||||
corresponding basic LLVM instructions.
|
corresponding basic LLVM instructions.
|
||||||
|
|
||||||
Beyond actually emitting the instruction, the implementations of
|
Beyond actually emitting the instruction, the implementations of
|
||||||
@@ -377,7 +377,7 @@ public:
|
|||||||
this also handles applying the given operation to the vector
|
this also handles applying the given operation to the vector
|
||||||
elements. */
|
elements. */
|
||||||
llvm::Value *BinaryOperator(llvm::Instruction::BinaryOps inst,
|
llvm::Value *BinaryOperator(llvm::Instruction::BinaryOps inst,
|
||||||
llvm::Value *v0, llvm::Value *v1,
|
llvm::Value *v0, llvm::Value *v1,
|
||||||
const char *name = NULL);
|
const char *name = NULL);
|
||||||
|
|
||||||
/** Emit the "not" operator. Like BinaryOperator(), this also handles
|
/** Emit the "not" operator. Like BinaryOperator(), this also handles
|
||||||
@@ -387,7 +387,7 @@ public:
|
|||||||
/** Emit a comparison instruction. If the operands are VectorTypes,
|
/** Emit a comparison instruction. If the operands are VectorTypes,
|
||||||
then a value for the corresponding boolean VectorType is
|
then a value for the corresponding boolean VectorType is
|
||||||
returned. */
|
returned. */
|
||||||
llvm::Value *CmpInst(llvm::Instruction::OtherOps inst,
|
llvm::Value *CmpInst(llvm::Instruction::OtherOps inst,
|
||||||
llvm::CmpInst::Predicate pred,
|
llvm::CmpInst::Predicate pred,
|
||||||
llvm::Value *v0, llvm::Value *v1, const char *name = NULL);
|
llvm::Value *v0, llvm::Value *v1, const char *name = NULL);
|
||||||
|
|
||||||
@@ -407,17 +407,17 @@ public:
|
|||||||
const char *name = NULL);
|
const char *name = NULL);
|
||||||
llvm::Instruction *CastInst(llvm::Instruction::CastOps op, llvm::Value *value,
|
llvm::Instruction *CastInst(llvm::Instruction::CastOps op, llvm::Value *value,
|
||||||
llvm::Type *type, const char *name = NULL);
|
llvm::Type *type, const char *name = NULL);
|
||||||
llvm::Instruction *FPCastInst(llvm::Value *value, llvm::Type *type,
|
llvm::Instruction *FPCastInst(llvm::Value *value, llvm::Type *type,
|
||||||
const char *name = NULL);
|
const char *name = NULL);
|
||||||
llvm::Instruction *SExtInst(llvm::Value *value, llvm::Type *type,
|
llvm::Instruction *SExtInst(llvm::Value *value, llvm::Type *type,
|
||||||
const char *name = NULL);
|
const char *name = NULL);
|
||||||
llvm::Instruction *ZExtInst(llvm::Value *value, llvm::Type *type,
|
llvm::Instruction *ZExtInst(llvm::Value *value, llvm::Type *type,
|
||||||
const char *name = NULL);
|
const char *name = NULL);
|
||||||
|
|
||||||
/** Given two integer-typed values (but possibly one vector and the
|
/** Given two integer-typed values (but possibly one vector and the
|
||||||
other not, and or of possibly-different bit-widths), update their
|
other not, and or of possibly-different bit-widths), update their
|
||||||
values as needed so that the two have the same (more general)
|
values as needed so that the two have the same (more general)
|
||||||
type. */
|
type. */
|
||||||
void MatchIntegerTypes(llvm::Value **v0, llvm::Value **v1);
|
void MatchIntegerTypes(llvm::Value **v0, llvm::Value **v1);
|
||||||
|
|
||||||
/** Create a new slice pointer out of the given pointer to an soa type
|
/** Create a new slice pointer out of the given pointer to an soa type
|
||||||
@@ -462,9 +462,9 @@ public:
|
|||||||
allocated at the given alignment. By default, the alloca
|
allocated at the given alignment. By default, the alloca
|
||||||
instruction is added at the start of the function in the entry
|
instruction is added at the start of the function in the entry
|
||||||
basic block; if it should be added to the current basic block, then
|
basic block; if it should be added to the current basic block, then
|
||||||
the atEntryBlock parameter should be false. */
|
the atEntryBlock parameter should be false. */
|
||||||
llvm::Value *AllocaInst(llvm::Type *llvmType,
|
llvm::Value *AllocaInst(llvm::Type *llvmType,
|
||||||
const char *name = NULL, int align = 0,
|
const char *name = NULL, int align = 0,
|
||||||
bool atEntryBlock = true);
|
bool atEntryBlock = true);
|
||||||
|
|
||||||
/** Standard store instruction; for this variant, the lvalue must be a
|
/** Standard store instruction; for this variant, the lvalue must be a
|
||||||
@@ -481,7 +481,7 @@ public:
|
|||||||
|
|
||||||
/** Copy count bytes of memory from the location pointed to by src to
|
/** Copy count bytes of memory from the location pointed to by src to
|
||||||
the location pointed to by dest. (src and dest must not be
|
the location pointed to by dest. (src and dest must not be
|
||||||
overlapping.) */
|
overlapping.) */
|
||||||
void MemcpyInst(llvm::Value *dest, llvm::Value *src, llvm::Value *count,
|
void MemcpyInst(llvm::Value *dest, llvm::Value *src, llvm::Value *count,
|
||||||
llvm::Value *align = NULL);
|
llvm::Value *align = NULL);
|
||||||
|
|
||||||
@@ -497,10 +497,10 @@ public:
|
|||||||
/** This convenience method maps to an llvm::InsertElementInst if the
|
/** This convenience method maps to an llvm::InsertElementInst if the
|
||||||
given value is a llvm::VectorType, and to an llvm::InsertValueInst
|
given value is a llvm::VectorType, and to an llvm::InsertValueInst
|
||||||
otherwise. */
|
otherwise. */
|
||||||
llvm::Value *InsertInst(llvm::Value *v, llvm::Value *eltVal, int elt,
|
llvm::Value *InsertInst(llvm::Value *v, llvm::Value *eltVal, int elt,
|
||||||
const char *name = NULL);
|
const char *name = NULL);
|
||||||
|
|
||||||
llvm::PHINode *PhiNode(llvm::Type *type, int count,
|
llvm::PHINode *PhiNode(llvm::Type *type, int count,
|
||||||
const char *name = NULL);
|
const char *name = NULL);
|
||||||
llvm::Instruction *SelectInst(llvm::Value *test, llvm::Value *val0,
|
llvm::Instruction *SelectInst(llvm::Value *test, llvm::Value *val0,
|
||||||
llvm::Value *val1, const char *name = NULL);
|
llvm::Value *val1, const char *name = NULL);
|
||||||
@@ -526,7 +526,7 @@ public:
|
|||||||
|
|
||||||
/** Launch an asynchronous task to run the given function, passing it
|
/** Launch an asynchronous task to run the given function, passing it
|
||||||
he given argument values. */
|
he given argument values. */
|
||||||
llvm::Value *LaunchInst(llvm::Value *callee,
|
llvm::Value *LaunchInst(llvm::Value *callee,
|
||||||
std::vector<llvm::Value *> &argVals,
|
std::vector<llvm::Value *> &argVals,
|
||||||
llvm::Value *launchCount);
|
llvm::Value *launchCount);
|
||||||
|
|
||||||
@@ -680,7 +680,7 @@ private:
|
|||||||
void jumpIfAllLoopLanesAreDone(llvm::BasicBlock *target);
|
void jumpIfAllLoopLanesAreDone(llvm::BasicBlock *target);
|
||||||
llvm::Value *emitGatherCallback(llvm::Value *lvalue, llvm::Value *retPtr);
|
llvm::Value *emitGatherCallback(llvm::Value *lvalue, llvm::Value *retPtr);
|
||||||
|
|
||||||
llvm::Value *applyVaryingGEP(llvm::Value *basePtr, llvm::Value *index,
|
llvm::Value *applyVaryingGEP(llvm::Value *basePtr, llvm::Value *index,
|
||||||
const Type *ptrType);
|
const Type *ptrType);
|
||||||
|
|
||||||
void restoreMaskGivenReturns(llvm::Value *oldMask);
|
void restoreMaskGivenReturns(llvm::Value *oldMask);
|
||||||
@@ -694,7 +694,7 @@ private:
|
|||||||
const Type *ptrType, llvm::Value *mask);
|
const Type *ptrType, llvm::Value *mask);
|
||||||
void maskedStore(llvm::Value *value, llvm::Value *ptr, const Type *ptrType,
|
void maskedStore(llvm::Value *value, llvm::Value *ptr, const Type *ptrType,
|
||||||
llvm::Value *mask);
|
llvm::Value *mask);
|
||||||
void storeUniformToSOA(llvm::Value *value, llvm::Value *ptr,
|
void storeUniformToSOA(llvm::Value *value, llvm::Value *ptr,
|
||||||
llvm::Value *mask, const Type *valueType,
|
llvm::Value *mask, const Type *valueType,
|
||||||
const PointerType *ptrType);
|
const PointerType *ptrType);
|
||||||
llvm::Value *loadUniformFromSOA(llvm::Value *ptr, llvm::Value *mask,
|
llvm::Value *loadUniformFromSOA(llvm::Value *ptr, llvm::Value *mask,
|
||||||
|
|||||||
36
decl.cpp
36
decl.cpp
@@ -28,11 +28,11 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file decl.cpp
|
/** @file decl.cpp
|
||||||
@brief Implementations of classes related to turning declarations into
|
@brief Implementations of classes related to turning declarations into
|
||||||
symbol names and types.
|
symbol names and types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ lPrintTypeQualifiers(int typeQualifiers) {
|
|||||||
|
|
||||||
|
|
||||||
/** Given a Type and a set of type qualifiers, apply the type qualifiers to
|
/** Given a Type and a set of type qualifiers, apply the type qualifiers to
|
||||||
the type, returning the type that is the result.
|
the type, returning the type that is the result.
|
||||||
*/
|
*/
|
||||||
static const Type *
|
static const Type *
|
||||||
lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
|
lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
|
||||||
@@ -97,7 +97,7 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
|
|||||||
if (unsignedType != NULL)
|
if (unsignedType != NULL)
|
||||||
type = unsignedType;
|
type = unsignedType;
|
||||||
else {
|
else {
|
||||||
const Type *resolvedType =
|
const Type *resolvedType =
|
||||||
type->ResolveUnboundVariability(Variability::Varying);
|
type->ResolveUnboundVariability(Variability::Varying);
|
||||||
Error(pos, "\"unsigned\" qualifier is illegal with \"%s\" type.",
|
Error(pos, "\"unsigned\" qualifier is illegal with \"%s\" type.",
|
||||||
resolvedType->GetString().c_str());
|
resolvedType->GetString().c_str());
|
||||||
@@ -105,7 +105,7 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((typeQualifiers & TYPEQUAL_SIGNED) != 0 && type->IsIntType() == false) {
|
if ((typeQualifiers & TYPEQUAL_SIGNED) != 0 && type->IsIntType() == false) {
|
||||||
const Type *resolvedType =
|
const Type *resolvedType =
|
||||||
type->ResolveUnboundVariability(Variability::Varying);
|
type->ResolveUnboundVariability(Variability::Varying);
|
||||||
Error(pos, "\"signed\" qualifier is illegal with non-integer type "
|
Error(pos, "\"signed\" qualifier is illegal with non-integer type "
|
||||||
"\"%s\".", resolvedType->GetString().c_str());
|
"\"%s\".", resolvedType->GetString().c_str());
|
||||||
@@ -147,7 +147,7 @@ DeclSpecs::GetBaseType(SourcePos pos) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
retType = lApplyTypeQualifiers(typeQualifiers, retType, pos);
|
retType = lApplyTypeQualifiers(typeQualifiers, retType, pos);
|
||||||
|
|
||||||
if (soaWidth > 0) {
|
if (soaWidth > 0) {
|
||||||
const StructType *st = CastType<StructType>(retType);
|
const StructType *st = CastType<StructType>(retType);
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ DeclSpecs::GetBaseType(SourcePos pos) const {
|
|||||||
"currently leads to inefficient code to access "
|
"currently leads to inefficient code to access "
|
||||||
"soa types.", soaWidth, g->target.vectorWidth);
|
"soa types.", soaWidth, g->target.vectorWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retType;
|
return retType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,8 +215,8 @@ DeclSpecs::Print() const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Declarator
|
// Declarator
|
||||||
|
|
||||||
Declarator::Declarator(DeclaratorKind dk, SourcePos p)
|
Declarator::Declarator(DeclaratorKind dk, SourcePos p)
|
||||||
: pos(p), kind(dk) {
|
: pos(p), kind(dk) {
|
||||||
child = NULL;
|
child = NULL;
|
||||||
typeQualifiers = 0;
|
typeQualifiers = 0;
|
||||||
storageClass = SC_NONE;
|
storageClass = SC_NONE;
|
||||||
@@ -238,7 +238,7 @@ Declarator::InitFromDeclSpecs(DeclSpecs *ds) {
|
|||||||
|
|
||||||
storageClass = ds->storageClass;
|
storageClass = ds->storageClass;
|
||||||
|
|
||||||
if (ds->declSpecList.size() > 0 &&
|
if (ds->declSpecList.size() > 0 &&
|
||||||
CastType<FunctionType>(type) == NULL) {
|
CastType<FunctionType>(type) == NULL) {
|
||||||
Error(pos, "__declspec specifiers for non-function type \"%s\" are "
|
Error(pos, "__declspec specifiers for non-function type \"%s\" are "
|
||||||
"not used.", type->GetString().c_str());
|
"not used.", type->GetString().c_str());
|
||||||
@@ -315,7 +315,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
|||||||
Error(pos, "\"export\" qualifier illegal in variable declaration.");
|
Error(pos, "\"export\" qualifier illegal in variable declaration.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variability variability(Variability::Unbound);
|
Variability variability(Variability::Unbound);
|
||||||
if (hasUniformQual)
|
if (hasUniformQual)
|
||||||
variability = Variability::Uniform;
|
variability = Variability::Uniform;
|
||||||
@@ -396,7 +396,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
|||||||
llvm::SmallVector<std::string, 8> argNames;
|
llvm::SmallVector<std::string, 8> argNames;
|
||||||
llvm::SmallVector<Expr *, 8> argDefaults;
|
llvm::SmallVector<Expr *, 8> argDefaults;
|
||||||
llvm::SmallVector<SourcePos, 8> argPos;
|
llvm::SmallVector<SourcePos, 8> argPos;
|
||||||
|
|
||||||
// Loop over the function arguments and store the names, types,
|
// Loop over the function arguments and store the names, types,
|
||||||
// default values (if any), and source file positions each one in
|
// default values (if any), and source file positions each one in
|
||||||
// the corresponding vector.
|
// the corresponding vector.
|
||||||
@@ -431,7 +431,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
|||||||
|
|
||||||
if (d->declSpecs->storageClass != SC_NONE)
|
if (d->declSpecs->storageClass != SC_NONE)
|
||||||
Error(decl->pos, "Storage class \"%s\" is illegal in "
|
Error(decl->pos, "Storage class \"%s\" is illegal in "
|
||||||
"function parameter declaration for parameter \"%s\".",
|
"function parameter declaration for parameter \"%s\".",
|
||||||
lGetStorageClassName(d->declSpecs->storageClass),
|
lGetStorageClassName(d->declSpecs->storageClass),
|
||||||
decl->name.c_str());
|
decl->name.c_str());
|
||||||
if (Type::Equal(decl->type, AtomicType::Void)) {
|
if (Type::Equal(decl->type, AtomicType::Void)) {
|
||||||
@@ -486,7 +486,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
|||||||
init = dynamic_cast<NullPointerExpr *>(decl->initExpr);
|
init = dynamic_cast<NullPointerExpr *>(decl->initExpr);
|
||||||
if (init == NULL)
|
if (init == NULL)
|
||||||
Error(decl->initExpr->pos, "Default value for parameter "
|
Error(decl->initExpr->pos, "Default value for parameter "
|
||||||
"\"%s\" must be a compile-time constant.",
|
"\"%s\" must be a compile-time constant.",
|
||||||
decl->name.c_str());
|
decl->name.c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -507,14 +507,14 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
|||||||
Error(pos, "Illegal to return function type from function.");
|
Error(pos, "Illegal to return function type from function.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
returnType = returnType->ResolveUnboundVariability(Variability::Varying);
|
returnType = returnType->ResolveUnboundVariability(Variability::Varying);
|
||||||
|
|
||||||
bool isExternC = ds && (ds->storageClass == SC_EXTERN_C);
|
bool isExternC = ds && (ds->storageClass == SC_EXTERN_C);
|
||||||
bool isExported = ds && ((ds->typeQualifiers & TYPEQUAL_EXPORT) != 0);
|
bool isExported = ds && ((ds->typeQualifiers & TYPEQUAL_EXPORT) != 0);
|
||||||
bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0);
|
bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0);
|
||||||
bool isUnmasked = ds && ((ds->typeQualifiers & TYPEQUAL_UNMASKED) != 0);
|
bool isUnmasked = ds && ((ds->typeQualifiers & TYPEQUAL_UNMASKED) != 0);
|
||||||
|
|
||||||
if (isExported && isTask) {
|
if (isExported && isTask) {
|
||||||
Error(pos, "Function can't have both \"task\" and \"export\" "
|
Error(pos, "Function can't have both \"task\" and \"export\" "
|
||||||
"qualifiers");
|
"qualifiers");
|
||||||
@@ -539,7 +539,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FunctionType *functionType =
|
const FunctionType *functionType =
|
||||||
new FunctionType(returnType, args, argNames, argDefaults,
|
new FunctionType(returnType, args, argNames, argDefaults,
|
||||||
argPos, isTask, isExported, isExternC, isUnmasked);
|
argPos, isTask, isExported, isExternC, isUnmasked);
|
||||||
|
|
||||||
@@ -669,7 +669,7 @@ GetStructTypesNamesPositions(const std::vector<StructDeclaration *> &sd,
|
|||||||
// disgusting
|
// disgusting
|
||||||
DeclSpecs ds(type);
|
DeclSpecs ds(type);
|
||||||
if (Type::Equal(type, AtomicType::Void) == false) {
|
if (Type::Equal(type, AtomicType::Void) == false) {
|
||||||
if (type->IsUniformType())
|
if (type->IsUniformType())
|
||||||
ds.typeQualifiers |= TYPEQUAL_UNIFORM;
|
ds.typeQualifiers |= TYPEQUAL_UNIFORM;
|
||||||
else if (type->IsVaryingType())
|
else if (type->IsVaryingType())
|
||||||
ds.typeQualifiers |= TYPEQUAL_VARYING;
|
ds.typeQualifiers |= TYPEQUAL_VARYING;
|
||||||
|
|||||||
8
decl.h
8
decl.h
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file decl.h
|
/** @file decl.h
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
qualifiers, and that it's basic type is 'int'. Then for each variable
|
qualifiers, and that it's basic type is 'int'. Then for each variable
|
||||||
declaration, the Declaraiton class holds an instance of a Declarator,
|
declaration, the Declaraiton class holds an instance of a Declarator,
|
||||||
which in turn records the per-variable information like the name, array
|
which in turn records the per-variable information like the name, array
|
||||||
size (if any), initializer expression, etc.
|
size (if any), initializer expression, etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ISPC_DECL_H
|
#ifndef ISPC_DECL_H
|
||||||
@@ -124,7 +124,7 @@ enum DeclaratorKind {
|
|||||||
DK_FUNCTION
|
DK_FUNCTION
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @brief Representation of the declaration of a single variable.
|
/** @brief Representation of the declaration of a single variable.
|
||||||
|
|
||||||
In conjunction with an instance of the DeclSpecs, this gives us
|
In conjunction with an instance of the DeclSpecs, this gives us
|
||||||
everything we need for a full variable declaration.
|
everything we need for a full variable declaration.
|
||||||
@@ -162,7 +162,7 @@ public:
|
|||||||
StorageClass storageClass;
|
StorageClass storageClass;
|
||||||
|
|
||||||
/** For array declarators, this gives the declared size of the array.
|
/** For array declarators, this gives the declared size of the array.
|
||||||
Unsized arrays have arraySize == 0. */
|
Unsized arrays have arraySize == 0. */
|
||||||
int arraySize;
|
int arraySize;
|
||||||
|
|
||||||
/** Name associated with the declarator. */
|
/** Name associated with the declarator. */
|
||||||
|
|||||||
24
expr.h
24
expr.h
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file expr.h
|
/** @file expr.h
|
||||||
@@ -101,7 +101,7 @@ class UnaryExpr : public Expr {
|
|||||||
public:
|
public:
|
||||||
enum Op {
|
enum Op {
|
||||||
PreInc, ///< Pre-increment
|
PreInc, ///< Pre-increment
|
||||||
PreDec, ///< Pre-decrement
|
PreDec, ///< Pre-decrement
|
||||||
PostInc, ///< Post-increment
|
PostInc, ///< Post-increment
|
||||||
PostDec, ///< Post-decrement
|
PostDec, ///< Post-decrement
|
||||||
Negate, ///< Negation
|
Negate, ///< Negation
|
||||||
@@ -198,7 +198,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** @brief Selection expression, corresponding to "test ? a : b".
|
/** @brief Selection expression, corresponding to "test ? a : b".
|
||||||
|
|
||||||
Returns the value of "a" or "b", depending on the value of "test".
|
Returns the value of "a" or "b", depending on the value of "test".
|
||||||
*/
|
*/
|
||||||
@@ -245,7 +245,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
class FunctionCallExpr : public Expr {
|
class FunctionCallExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
FunctionCallExpr(Expr *func, ExprList *args, SourcePos p,
|
FunctionCallExpr(Expr *func, ExprList *args, SourcePos p,
|
||||||
bool isLaunch = false, Expr *launchCountExpr = NULL);
|
bool isLaunch = false, Expr *launchCountExpr = NULL);
|
||||||
|
|
||||||
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
||||||
@@ -266,7 +266,7 @@ public:
|
|||||||
/** @brief Expression representing indexing into something with an integer
|
/** @brief Expression representing indexing into something with an integer
|
||||||
offset.
|
offset.
|
||||||
|
|
||||||
This is used for both array indexing and indexing into VectorTypes.
|
This is used for both array indexing and indexing into VectorTypes.
|
||||||
*/
|
*/
|
||||||
class IndexExpr : public Expr {
|
class IndexExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
@@ -317,7 +317,7 @@ public:
|
|||||||
std::string identifier;
|
std::string identifier;
|
||||||
const SourcePos identifierPos;
|
const SourcePos identifierPos;
|
||||||
|
|
||||||
MemberExpr(Expr *expr, const char *identifier, SourcePos pos,
|
MemberExpr(Expr *expr, const char *identifier, SourcePos pos,
|
||||||
SourcePos identifierPos, bool derefLValue);
|
SourcePos identifierPos, bool derefLValue);
|
||||||
|
|
||||||
/** Indicates whether the expression should be dereferenced before the
|
/** Indicates whether the expression should be dereferenced before the
|
||||||
@@ -330,7 +330,7 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** @brief Expression representing a compile-time constant value.
|
/** @brief Expression representing a compile-time constant value.
|
||||||
|
|
||||||
This class can currently represent compile-time constants of anything
|
This class can currently represent compile-time constants of anything
|
||||||
that is an AtomicType or an EnumType; for anything more complex, we
|
that is an AtomicType or an EnumType; for anything more complex, we
|
||||||
@@ -640,7 +640,7 @@ private:
|
|||||||
|
|
||||||
/** @brief Expression representing a function symbol in the program (generally
|
/** @brief Expression representing a function symbol in the program (generally
|
||||||
used for a function call).
|
used for a function call).
|
||||||
*/
|
*/
|
||||||
class FunctionSymbolExpr : public Expr {
|
class FunctionSymbolExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
FunctionSymbolExpr(const char *name, const std::vector<Symbol *> &candFuncs,
|
FunctionSymbolExpr(const char *name, const std::vector<Symbol *> &candFuncs,
|
||||||
@@ -714,7 +714,7 @@ public:
|
|||||||
class NullPointerExpr : public Expr {
|
class NullPointerExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
NullPointerExpr(SourcePos p) : Expr(p) { }
|
NullPointerExpr(SourcePos p) : Expr(p) { }
|
||||||
|
|
||||||
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
||||||
const Type *GetType() const;
|
const Type *GetType() const;
|
||||||
Expr *TypeCheck();
|
Expr *TypeCheck();
|
||||||
@@ -726,11 +726,11 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/** An expression representing a "new" expression, used for dynamically
|
/** An expression representing a "new" expression, used for dynamically
|
||||||
allocating memory.
|
allocating memory.
|
||||||
*/
|
*/
|
||||||
class NewExpr : public Expr {
|
class NewExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
NewExpr(int typeQual, const Type *type, Expr *initializer, Expr *count,
|
NewExpr(int typeQual, const Type *type, Expr *initializer, Expr *count,
|
||||||
SourcePos tqPos, SourcePos p);
|
SourcePos tqPos, SourcePos p);
|
||||||
|
|
||||||
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
||||||
@@ -742,7 +742,7 @@ public:
|
|||||||
|
|
||||||
/** Type of object to allocate storage for. */
|
/** Type of object to allocate storage for. */
|
||||||
const Type *allocType;
|
const Type *allocType;
|
||||||
/** Expression giving the number of elements to allocate, when the
|
/** Expression giving the number of elements to allocate, when the
|
||||||
"new Foo[expr]" form is used. This may be NULL, in which case a
|
"new Foo[expr]" form is used. This may be NULL, in which case a
|
||||||
single element of the given type will be allocated. */
|
single element of the given type will be allocated. */
|
||||||
Expr *countExpr;
|
Expr *countExpr;
|
||||||
|
|||||||
32
func.cpp
32
func.cpp
@@ -28,11 +28,11 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file func.cpp
|
/** @file func.cpp
|
||||||
@brief
|
@brief
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "func.h"
|
#include "func.h"
|
||||||
@@ -85,7 +85,7 @@ Function::Function(Symbol *s, Stmt *c) {
|
|||||||
code = TypeCheck(code);
|
code = TypeCheck(code);
|
||||||
|
|
||||||
if (code != NULL && g->debugPrint) {
|
if (code != NULL && g->debugPrint) {
|
||||||
fprintf(stderr, "After typechecking function \"%s\":\n",
|
fprintf(stderr, "After typechecking function \"%s\":\n",
|
||||||
sym->name.c_str());
|
sym->name.c_str());
|
||||||
code->Print(0);
|
code->Print(0);
|
||||||
fprintf(stderr, "---------------------\n");
|
fprintf(stderr, "---------------------\n");
|
||||||
@@ -94,7 +94,7 @@ Function::Function(Symbol *s, Stmt *c) {
|
|||||||
if (code != NULL) {
|
if (code != NULL) {
|
||||||
code = Optimize(code);
|
code = Optimize(code);
|
||||||
if (g->debugPrint) {
|
if (g->debugPrint) {
|
||||||
fprintf(stderr, "After optimizing function \"%s\":\n",
|
fprintf(stderr, "After optimizing function \"%s\":\n",
|
||||||
sym->name.c_str());
|
sym->name.c_str());
|
||||||
code->Print(0);
|
code->Print(0);
|
||||||
fprintf(stderr, "---------------------\n");
|
fprintf(stderr, "---------------------\n");
|
||||||
@@ -160,7 +160,7 @@ Function::GetType() const {
|
|||||||
'mem2reg' pass will in turn promote to SSA registers..
|
'mem2reg' pass will in turn promote to SSA registers..
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const
|
lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const
|
||||||
std::vector<Symbol *> &args,
|
std::vector<Symbol *> &args,
|
||||||
FunctionEmitContext *ctx) {
|
FunctionEmitContext *ctx) {
|
||||||
// We expect the argument structure to come in as a poitner to a
|
// We expect the argument structure to come in as a poitner to a
|
||||||
@@ -169,7 +169,7 @@ lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const
|
|||||||
Assert(llvm::isa<llvm::PointerType>(structArgType));
|
Assert(llvm::isa<llvm::PointerType>(structArgType));
|
||||||
const llvm::PointerType *pt = llvm::dyn_cast<const llvm::PointerType>(structArgType);
|
const llvm::PointerType *pt = llvm::dyn_cast<const llvm::PointerType>(structArgType);
|
||||||
Assert(llvm::isa<llvm::StructType>(pt->getElementType()));
|
Assert(llvm::isa<llvm::StructType>(pt->getElementType()));
|
||||||
const llvm::StructType *argStructType =
|
const llvm::StructType *argStructType =
|
||||||
llvm::dyn_cast<const llvm::StructType>(pt->getElementType());
|
llvm::dyn_cast<const llvm::StructType>(pt->getElementType());
|
||||||
|
|
||||||
// Get the type of the argument we're copying in and its Symbol pointer
|
// Get the type of the argument we're copying in and its Symbol pointer
|
||||||
@@ -199,8 +199,8 @@ lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const
|
|||||||
involves wiring up the function parameter values to be available in the
|
involves wiring up the function parameter values to be available in the
|
||||||
function body code.
|
function body code.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
||||||
SourcePos firstStmtPos) {
|
SourcePos firstStmtPos) {
|
||||||
// Connect the __mask builtin to the location in memory that stores its
|
// Connect the __mask builtin to the location in memory that stores its
|
||||||
// value
|
// value
|
||||||
@@ -259,7 +259,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Regular, non-task function
|
// Regular, non-task function
|
||||||
llvm::Function::arg_iterator argIter = function->arg_begin();
|
llvm::Function::arg_iterator argIter = function->arg_begin();
|
||||||
for (unsigned int i = 0; i < args.size(); ++i, ++argIter) {
|
for (unsigned int i = 0; i < args.size(); ++i, ++argIter) {
|
||||||
Symbol *sym = args[i];
|
Symbol *sym = args[i];
|
||||||
if (sym == NULL)
|
if (sym == NULL)
|
||||||
@@ -301,14 +301,14 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
|||||||
ctx->AddInstrumentationPoint("function entry");
|
ctx->AddInstrumentationPoint("function entry");
|
||||||
|
|
||||||
int costEstimate = EstimateCost(code);
|
int costEstimate = EstimateCost(code);
|
||||||
Debug(code->pos, "Estimated cost for function \"%s\" = %d\n",
|
Debug(code->pos, "Estimated cost for function \"%s\" = %d\n",
|
||||||
sym->name.c_str(), costEstimate);
|
sym->name.c_str(), costEstimate);
|
||||||
|
|
||||||
// If the body of the function is non-trivial, then we wrap the
|
// If the body of the function is non-trivial, then we wrap the
|
||||||
// entire thing inside code that tests to see if the mask is all
|
// entire thing inside code that tests to see if the mask is all
|
||||||
// on, all off, or mixed. If this is a simple function, then this
|
// on, all off, or mixed. If this is a simple function, then this
|
||||||
// isn't worth the code bloat / overhead.
|
// isn't worth the code bloat / overhead.
|
||||||
bool checkMask = (type->isTask == true) ||
|
bool checkMask = (type->isTask == true) ||
|
||||||
(
|
(
|
||||||
#if defined(LLVM_3_1)
|
#if defined(LLVM_3_1)
|
||||||
(function->hasFnAttr(llvm::Attribute::AlwaysInline) == false)
|
(function->hasFnAttr(llvm::Attribute::AlwaysInline) == false)
|
||||||
@@ -322,7 +322,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
|||||||
checkMask &= (type->isUnmasked == false);
|
checkMask &= (type->isUnmasked == false);
|
||||||
checkMask &= (g->target.maskingIsFree == false);
|
checkMask &= (g->target.maskingIsFree == false);
|
||||||
checkMask &= (g->opt.disableCoherentControlFlow == false);
|
checkMask &= (g->opt.disableCoherentControlFlow == false);
|
||||||
|
|
||||||
if (checkMask) {
|
if (checkMask) {
|
||||||
llvm::Value *mask = ctx->GetFunctionMask();
|
llvm::Value *mask = ctx->GetFunctionMask();
|
||||||
llvm::Value *allOn = ctx->All(mask);
|
llvm::Value *allOn = ctx->All(mask);
|
||||||
@@ -409,7 +409,7 @@ Function::GenerateIR() {
|
|||||||
|
|
||||||
// But if that function has a definition, we don't want to redefine it.
|
// But if that function has a definition, we don't want to redefine it.
|
||||||
if (function->empty() == false) {
|
if (function->empty() == false) {
|
||||||
Error(sym->pos, "Ignoring redefinition of function \"%s\".",
|
Error(sym->pos, "Ignoring redefinition of function \"%s\".",
|
||||||
sym->name.c_str());
|
sym->name.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -426,7 +426,7 @@ Function::GenerateIR() {
|
|||||||
firstStmtPos = code->pos;
|
firstStmtPos = code->pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// And we can now go ahead and emit the code
|
// And we can now go ahead and emit the code
|
||||||
{
|
{
|
||||||
FunctionEmitContext ec(this, sym, function, firstStmtPos);
|
FunctionEmitContext ec(this, sym, function, firstStmtPos);
|
||||||
emitCode(&ec, function, firstStmtPos);
|
emitCode(&ec, function, firstStmtPos);
|
||||||
@@ -451,7 +451,7 @@ Function::GenerateIR() {
|
|||||||
std::string functionName = sym->name;
|
std::string functionName = sym->name;
|
||||||
if (g->mangleFunctionsWithTarget)
|
if (g->mangleFunctionsWithTarget)
|
||||||
functionName += std::string("_") + g->target.GetISAString();
|
functionName += std::string("_") + g->target.GetISAString();
|
||||||
llvm::Function *appFunction =
|
llvm::Function *appFunction =
|
||||||
llvm::Function::Create(ftype, linkage, functionName.c_str(), m->module);
|
llvm::Function::Create(ftype, linkage, functionName.c_str(), m->module);
|
||||||
#if defined(LLVM_3_1)
|
#if defined(LLVM_3_1)
|
||||||
appFunction->setDoesNotThrow(true);
|
appFunction->setDoesNotThrow(true);
|
||||||
@@ -470,7 +470,7 @@ Function::GenerateIR() {
|
|||||||
emitCode(&ec, appFunction, firstStmtPos);
|
emitCode(&ec, appFunction, firstStmtPos);
|
||||||
if (m->errorCount == 0) {
|
if (m->errorCount == 0) {
|
||||||
sym->exportedFunction = appFunction;
|
sym->exportedFunction = appFunction;
|
||||||
if (llvm::verifyFunction(*appFunction,
|
if (llvm::verifyFunction(*appFunction,
|
||||||
llvm::ReturnStatusAction) == true) {
|
llvm::ReturnStatusAction) == true) {
|
||||||
if (g->debugPrint)
|
if (g->debugPrint)
|
||||||
appFunction->dump();
|
appFunction->dump();
|
||||||
|
|||||||
4
func.h
4
func.h
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file func.h
|
/** @file func.h
|
||||||
@@ -52,7 +52,7 @@ public:
|
|||||||
void GenerateIR();
|
void GenerateIR();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
void emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
||||||
SourcePos firstStmtPos);
|
SourcePos firstStmtPos);
|
||||||
|
|
||||||
Symbol *sym;
|
Symbol *sym;
|
||||||
|
|||||||
42
ispc.cpp
42
ispc.cpp
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file ispc.cpp
|
/** @file ispc.cpp
|
||||||
@@ -136,7 +136,7 @@ lGetSystemISA() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *supportedCPUs[] = {
|
static const char *supportedCPUs[] = {
|
||||||
"atom", "penryn", "core2", "corei7", "corei7-avx"
|
"atom", "penryn", "core2", "corei7", "corei7-avx"
|
||||||
#if defined(LLVM_3_2) || defined(LLVM_3_3)
|
#if defined(LLVM_3_2) || defined(LLVM_3_3)
|
||||||
, "core-avx-i", "core-avx2"
|
, "core-avx-i", "core-avx2"
|
||||||
@@ -187,7 +187,7 @@ Target::GetTarget(const char *arch, const char *cpu, const char *isa,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bool foundCPU = false;
|
bool foundCPU = false;
|
||||||
for (int i = 0; i < int(sizeof(supportedCPUs) / sizeof(supportedCPUs[0]));
|
for (int i = 0; i < int(sizeof(supportedCPUs) / sizeof(supportedCPUs[0]));
|
||||||
++i) {
|
++i) {
|
||||||
if (!strcmp(cpu, supportedCPUs[i])) {
|
if (!strcmp(cpu, supportedCPUs[i])) {
|
||||||
foundCPU = true;
|
foundCPU = true;
|
||||||
@@ -405,7 +405,7 @@ Target::GetTarget(const char *arch, const char *cpu, const char *isa,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "Target ISA \"%s\" is unknown. Choices are: %s\n",
|
fprintf(stderr, "Target ISA \"%s\" is unknown. Choices are: %s\n",
|
||||||
isa, SupportedTargetISAs());
|
isa, SupportedTargetISAs());
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -494,7 +494,7 @@ llvm::TargetMachine *
|
|||||||
Target::GetTargetMachine() const {
|
Target::GetTargetMachine() const {
|
||||||
std::string triple = GetTripleString();
|
std::string triple = GetTripleString();
|
||||||
|
|
||||||
llvm::Reloc::Model relocModel = generatePIC ? llvm::Reloc::PIC_ :
|
llvm::Reloc::Model relocModel = generatePIC ? llvm::Reloc::PIC_ :
|
||||||
llvm::Reloc::Default;
|
llvm::Reloc::Default;
|
||||||
std::string featuresString = attributes;
|
std::string featuresString = attributes;
|
||||||
llvm::TargetOptions options;
|
llvm::TargetOptions options;
|
||||||
@@ -502,7 +502,7 @@ Target::GetTargetMachine() const {
|
|||||||
if (g->opt.disableFMA == false)
|
if (g->opt.disableFMA == false)
|
||||||
options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
|
options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
|
||||||
#endif // !LLVM_3_1
|
#endif // !LLVM_3_1
|
||||||
llvm::TargetMachine *targetMachine =
|
llvm::TargetMachine *targetMachine =
|
||||||
target->createTargetMachine(triple, cpu, featuresString, options,
|
target->createTargetMachine(triple, cpu, featuresString, options,
|
||||||
relocModel);
|
relocModel);
|
||||||
Assert(targetMachine != NULL);
|
Assert(targetMachine != NULL);
|
||||||
@@ -544,12 +544,12 @@ lGenericTypeLayoutIndeterminate(llvm::Type *type) {
|
|||||||
type == LLVMTypes::Int1VectorType)
|
type == LLVMTypes::Int1VectorType)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
llvm::ArrayType *at =
|
llvm::ArrayType *at =
|
||||||
llvm::dyn_cast<llvm::ArrayType>(type);
|
llvm::dyn_cast<llvm::ArrayType>(type);
|
||||||
if (at != NULL)
|
if (at != NULL)
|
||||||
return lGenericTypeLayoutIndeterminate(at->getElementType());
|
return lGenericTypeLayoutIndeterminate(at->getElementType());
|
||||||
|
|
||||||
llvm::PointerType *pt =
|
llvm::PointerType *pt =
|
||||||
llvm::dyn_cast<llvm::PointerType>(type);
|
llvm::dyn_cast<llvm::PointerType>(type);
|
||||||
if (pt != NULL)
|
if (pt != NULL)
|
||||||
return false;
|
return false;
|
||||||
@@ -569,7 +569,7 @@ lGenericTypeLayoutIndeterminate(llvm::Type *type) {
|
|||||||
|
|
||||||
|
|
||||||
llvm::Value *
|
llvm::Value *
|
||||||
Target::SizeOf(llvm::Type *type,
|
Target::SizeOf(llvm::Type *type,
|
||||||
llvm::BasicBlock *insertAtEnd) {
|
llvm::BasicBlock *insertAtEnd) {
|
||||||
if (isa == Target::GENERIC &&
|
if (isa == Target::GENERIC &&
|
||||||
lGenericTypeLayoutIndeterminate(type)) {
|
lGenericTypeLayoutIndeterminate(type)) {
|
||||||
@@ -577,15 +577,15 @@ Target::SizeOf(llvm::Type *type,
|
|||||||
llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
|
llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
|
||||||
llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
|
llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
|
||||||
llvm::ArrayRef<llvm::Value *> arrayRef(&index[0], &index[1]);
|
llvm::ArrayRef<llvm::Value *> arrayRef(&index[0], &index[1]);
|
||||||
llvm::Instruction *gep =
|
llvm::Instruction *gep =
|
||||||
llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "sizeof_gep",
|
llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "sizeof_gep",
|
||||||
insertAtEnd);
|
insertAtEnd);
|
||||||
|
|
||||||
if (is32Bit || g->opt.force32BitAddressing)
|
if (is32Bit || g->opt.force32BitAddressing)
|
||||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
|
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
|
||||||
"sizeof_int", insertAtEnd);
|
"sizeof_int", insertAtEnd);
|
||||||
else
|
else
|
||||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
|
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
|
||||||
"sizeof_int", insertAtEnd);
|
"sizeof_int", insertAtEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,25 +611,25 @@ Target::SizeOf(llvm::Type *type,
|
|||||||
llvm::Value *
|
llvm::Value *
|
||||||
Target::StructOffset(llvm::Type *type, int element,
|
Target::StructOffset(llvm::Type *type, int element,
|
||||||
llvm::BasicBlock *insertAtEnd) {
|
llvm::BasicBlock *insertAtEnd) {
|
||||||
if (isa == Target::GENERIC &&
|
if (isa == Target::GENERIC &&
|
||||||
lGenericTypeLayoutIndeterminate(type) == true) {
|
lGenericTypeLayoutIndeterminate(type) == true) {
|
||||||
llvm::Value *indices[2] = { LLVMInt32(0), LLVMInt32(element) };
|
llvm::Value *indices[2] = { LLVMInt32(0), LLVMInt32(element) };
|
||||||
llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
|
llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
|
||||||
llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
|
llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
|
||||||
llvm::ArrayRef<llvm::Value *> arrayRef(&indices[0], &indices[2]);
|
llvm::ArrayRef<llvm::Value *> arrayRef(&indices[0], &indices[2]);
|
||||||
llvm::Instruction *gep =
|
llvm::Instruction *gep =
|
||||||
llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "offset_gep",
|
llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "offset_gep",
|
||||||
insertAtEnd);
|
insertAtEnd);
|
||||||
|
|
||||||
if (is32Bit || g->opt.force32BitAddressing)
|
if (is32Bit || g->opt.force32BitAddressing)
|
||||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
|
return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type,
|
||||||
"offset_int", insertAtEnd);
|
"offset_int", insertAtEnd);
|
||||||
else
|
else
|
||||||
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
|
return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type,
|
||||||
"offset_int", insertAtEnd);
|
"offset_int", insertAtEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::StructType *structType =
|
llvm::StructType *structType =
|
||||||
llvm::dyn_cast<llvm::StructType>(type);
|
llvm::dyn_cast<llvm::StructType>(type);
|
||||||
if (structType == NULL || structType->isSized() == false) {
|
if (structType == NULL || structType->isSized() == false) {
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
@@ -699,7 +699,7 @@ Globals::Globals() {
|
|||||||
enableFuzzTest = false;
|
enableFuzzTest = false;
|
||||||
fuzzTestSeed = -1;
|
fuzzTestSeed = -1;
|
||||||
mangleFunctionsWithTarget = false;
|
mangleFunctionsWithTarget = false;
|
||||||
|
|
||||||
ctx = new llvm::LLVMContext;
|
ctx = new llvm::LLVMContext;
|
||||||
|
|
||||||
#ifdef ISPC_IS_WINDOWS
|
#ifdef ISPC_IS_WINDOWS
|
||||||
@@ -739,15 +739,15 @@ SourcePos::GetDIFile() const {
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SourcePos::Print() const {
|
SourcePos::Print() const {
|
||||||
printf(" @ [%s:%d.%d - %d.%d] ", name, first_line, first_column,
|
printf(" @ [%s:%d.%d - %d.%d] ", name, first_line, first_column,
|
||||||
last_line, last_column);
|
last_line, last_column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SourcePos::operator==(const SourcePos &p2) const {
|
SourcePos::operator==(const SourcePos &p2) const {
|
||||||
return (!strcmp(name, p2.name) &&
|
return (!strcmp(name, p2.name) &&
|
||||||
first_line == p2.first_line &&
|
first_line == p2.first_line &&
|
||||||
first_column == p2.first_column &&
|
first_column == p2.first_column &&
|
||||||
last_line == p2.last_line &&
|
last_line == p2.last_line &&
|
||||||
|
|||||||
18
ispc.h
18
ispc.h
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file ispc.h
|
/** @file ispc.h
|
||||||
@@ -158,7 +158,7 @@ extern void DoAssertPos(SourcePos pos, const char *file, int line, const char *e
|
|||||||
((void)((expr) ? 0 : ((void)DoAssertPos (pos, __FILE__, __LINE__, #expr), 0)))
|
((void)((expr) ? 0 : ((void)DoAssertPos (pos, __FILE__, __LINE__, #expr), 0)))
|
||||||
|
|
||||||
|
|
||||||
/** @brief Structure that defines a compilation target
|
/** @brief Structure that defines a compilation target
|
||||||
|
|
||||||
This structure defines a compilation target for the ispc compiler.
|
This structure defines a compilation target for the ispc compiler.
|
||||||
*/
|
*/
|
||||||
@@ -188,7 +188,7 @@ struct Target {
|
|||||||
/** Returns the LLVM TargetMachine object corresponding to this
|
/** Returns the LLVM TargetMachine object corresponding to this
|
||||||
target. */
|
target. */
|
||||||
llvm::TargetMachine *GetTargetMachine() const;
|
llvm::TargetMachine *GetTargetMachine() const;
|
||||||
|
|
||||||
/** Returns a string like "avx" encoding the target. */
|
/** Returns a string like "avx" encoding the target. */
|
||||||
const char *GetISAString() const;
|
const char *GetISAString() const;
|
||||||
|
|
||||||
@@ -281,11 +281,11 @@ struct Target {
|
|||||||
/** @brief Structure that collects optimization options
|
/** @brief Structure that collects optimization options
|
||||||
|
|
||||||
This structure collects all of the options related to optimization of
|
This structure collects all of the options related to optimization of
|
||||||
generated code.
|
generated code.
|
||||||
*/
|
*/
|
||||||
struct Opt {
|
struct Opt {
|
||||||
Opt();
|
Opt();
|
||||||
|
|
||||||
/** Optimization level. Currently, the only valid values are 0,
|
/** Optimization level. Currently, the only valid values are 0,
|
||||||
indicating essentially no optimization, and 1, indicating as much
|
indicating essentially no optimization, and 1, indicating as much
|
||||||
optimization as possible. */
|
optimization as possible. */
|
||||||
@@ -308,7 +308,7 @@ struct Opt {
|
|||||||
/** Indicates if addressing math will be done with 32-bit math, even on
|
/** Indicates if addressing math will be done with 32-bit math, even on
|
||||||
64-bit systems. (This is generally noticably more efficient,
|
64-bit systems. (This is generally noticably more efficient,
|
||||||
though at the cost of addressing >2GB).
|
though at the cost of addressing >2GB).
|
||||||
*/
|
*/
|
||||||
bool force32BitAddressing;
|
bool force32BitAddressing;
|
||||||
|
|
||||||
/** Indicates whether Assert() statements should be ignored (for
|
/** Indicates whether Assert() statements should be ignored (for
|
||||||
@@ -387,7 +387,7 @@ struct Opt {
|
|||||||
bool disableCoalescing;
|
bool disableCoalescing;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @brief This structure collects together a number of global variables.
|
/** @brief This structure collects together a number of global variables.
|
||||||
|
|
||||||
This structure collects a number of global variables that mostly
|
This structure collects a number of global variables that mostly
|
||||||
represent parameter settings for this compilation run. In particular,
|
represent parameter settings for this compilation run. In particular,
|
||||||
@@ -445,12 +445,12 @@ struct Globals {
|
|||||||
externally-defined program instrumentation function. (See the
|
externally-defined program instrumentation function. (See the
|
||||||
"Instrumenting your ispc programs" section in the user's
|
"Instrumenting your ispc programs" section in the user's
|
||||||
manual.) */
|
manual.) */
|
||||||
bool emitInstrumentation;
|
bool emitInstrumentation;
|
||||||
|
|
||||||
/** Indicates whether ispc should generate debugging symbols for the
|
/** Indicates whether ispc should generate debugging symbols for the
|
||||||
program in its output. */
|
program in its output. */
|
||||||
bool generateDebuggingSymbols;
|
bool generateDebuggingSymbols;
|
||||||
|
|
||||||
/** If true, function names are mangled by appending the target ISA and
|
/** If true, function names are mangled by appending the target ISA and
|
||||||
vector width to them. */
|
vector width to them. */
|
||||||
bool mangleFunctionsWithTarget;
|
bool mangleFunctionsWithTarget;
|
||||||
|
|||||||
48
lex.ll
48
lex.ll
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
%{
|
%{
|
||||||
@@ -62,7 +62,7 @@ inline int isatty(int) { return 0; }
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif // ISPC_IS_WINDOWS
|
#endif // ISPC_IS_WINDOWS
|
||||||
|
|
||||||
static int allTokens[] = {
|
static int allTokens[] = {
|
||||||
TOKEN_ASSERT, TOKEN_BOOL, TOKEN_BREAK, TOKEN_CASE,
|
TOKEN_ASSERT, TOKEN_BOOL, TOKEN_BREAK, TOKEN_CASE,
|
||||||
TOKEN_CDO, TOKEN_CFOR, TOKEN_CIF, TOKEN_CWHILE,
|
TOKEN_CDO, TOKEN_CFOR, TOKEN_CIF, TOKEN_CWHILE,
|
||||||
TOKEN_CONST, TOKEN_CONTINUE, TOKEN_DEFAULT, TOKEN_DO,
|
TOKEN_CONST, TOKEN_CONTINUE, TOKEN_DEFAULT, TOKEN_DO,
|
||||||
@@ -74,11 +74,11 @@ static int allTokens[] = {
|
|||||||
TOKEN_NEW, TOKEN_NULL, TOKEN_PRINT, TOKEN_RETURN, TOKEN_SOA, TOKEN_SIGNED,
|
TOKEN_NEW, TOKEN_NULL, TOKEN_PRINT, TOKEN_RETURN, TOKEN_SOA, TOKEN_SIGNED,
|
||||||
TOKEN_SIZEOF, TOKEN_STATIC, TOKEN_STRUCT, TOKEN_SWITCH, TOKEN_SYNC,
|
TOKEN_SIZEOF, TOKEN_STATIC, TOKEN_STRUCT, TOKEN_SWITCH, TOKEN_SYNC,
|
||||||
TOKEN_TASK, TOKEN_TRUE, TOKEN_TYPEDEF, TOKEN_UNIFORM, TOKEN_UNMASKED,
|
TOKEN_TASK, TOKEN_TRUE, TOKEN_TYPEDEF, TOKEN_UNIFORM, TOKEN_UNMASKED,
|
||||||
TOKEN_UNSIGNED, TOKEN_VARYING, TOKEN_VOID, TOKEN_WHILE,
|
TOKEN_UNSIGNED, TOKEN_VARYING, TOKEN_VOID, TOKEN_WHILE,
|
||||||
TOKEN_STRING_C_LITERAL, TOKEN_DOTDOTDOT,
|
TOKEN_STRING_C_LITERAL, TOKEN_DOTDOTDOT,
|
||||||
TOKEN_FLOAT_CONSTANT,
|
TOKEN_FLOAT_CONSTANT,
|
||||||
TOKEN_INT32_CONSTANT, TOKEN_UINT32_CONSTANT,
|
TOKEN_INT32_CONSTANT, TOKEN_UINT32_CONSTANT,
|
||||||
TOKEN_INT64_CONSTANT, TOKEN_UINT64_CONSTANT,
|
TOKEN_INT64_CONSTANT, TOKEN_UINT64_CONSTANT,
|
||||||
TOKEN_INC_OP, TOKEN_DEC_OP, TOKEN_LEFT_OP, TOKEN_RIGHT_OP, TOKEN_LE_OP,
|
TOKEN_INC_OP, TOKEN_DEC_OP, TOKEN_LEFT_OP, TOKEN_RIGHT_OP, TOKEN_LE_OP,
|
||||||
TOKEN_GE_OP, TOKEN_EQ_OP, TOKEN_NE_OP, TOKEN_AND_OP, TOKEN_OR_OP,
|
TOKEN_GE_OP, TOKEN_EQ_OP, TOKEN_NE_OP, TOKEN_AND_OP, TOKEN_OR_OP,
|
||||||
TOKEN_MUL_ASSIGN, TOKEN_DIV_ASSIGN, TOKEN_MOD_ASSIGN, TOKEN_ADD_ASSIGN,
|
TOKEN_MUL_ASSIGN, TOKEN_DIV_ASSIGN, TOKEN_MOD_ASSIGN, TOKEN_ADD_ASSIGN,
|
||||||
@@ -406,7 +406,7 @@ while { RT; return TOKEN_WHILE; }
|
|||||||
|
|
||||||
L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERAL; }
|
L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERAL; }
|
||||||
|
|
||||||
{IDENT} {
|
{IDENT} {
|
||||||
RT;
|
RT;
|
||||||
/* We have an identifier--is it a type name or an identifier?
|
/* We have an identifier--is it a type name or an identifier?
|
||||||
The symbol table will straighten us out... */
|
The symbol table will straighten us out... */
|
||||||
@@ -414,10 +414,10 @@ L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERA
|
|||||||
if (m->symbolTable->LookupType(yytext) != NULL)
|
if (m->symbolTable->LookupType(yytext) != NULL)
|
||||||
return TOKEN_TYPE_NAME;
|
return TOKEN_TYPE_NAME;
|
||||||
else
|
else
|
||||||
return TOKEN_IDENTIFIER;
|
return TOKEN_IDENTIFIER;
|
||||||
}
|
}
|
||||||
|
|
||||||
{INT_NUMBER} {
|
{INT_NUMBER} {
|
||||||
RT;
|
RT;
|
||||||
return lParseInteger(false);
|
return lParseInteger(false);
|
||||||
}
|
}
|
||||||
@@ -428,16 +428,16 @@ L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERA
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{FLOAT_NUMBER} {
|
{FLOAT_NUMBER} {
|
||||||
RT;
|
RT;
|
||||||
yylval.floatVal = (float)atof(yytext);
|
yylval.floatVal = (float)atof(yytext);
|
||||||
return TOKEN_FLOAT_CONSTANT;
|
return TOKEN_FLOAT_CONSTANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
{HEX_FLOAT_NUMBER} {
|
{HEX_FLOAT_NUMBER} {
|
||||||
RT;
|
RT;
|
||||||
yylval.floatVal = (float)lParseHexFloat(yytext);
|
yylval.floatVal = (float)lParseHexFloat(yytext);
|
||||||
return TOKEN_FLOAT_CONSTANT;
|
return TOKEN_FLOAT_CONSTANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
"++" { RT; return TOKEN_INC_OP; }
|
"++" { RT; return TOKEN_INC_OP; }
|
||||||
@@ -489,17 +489,17 @@ L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERA
|
|||||||
{WHITESPACE} { }
|
{WHITESPACE} { }
|
||||||
|
|
||||||
\n {
|
\n {
|
||||||
yylloc.last_line++;
|
yylloc.last_line++;
|
||||||
yylloc.last_column = 1;
|
yylloc.last_column = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#(line)?[ ][0-9]+[ ]\"(\\.|[^\\"])*\"[^\n]* {
|
#(line)?[ ][0-9]+[ ]\"(\\.|[^\\"])*\"[^\n]* {
|
||||||
lHandleCppHash(&yylloc);
|
lHandleCppHash(&yylloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
. {
|
. {
|
||||||
Error(yylloc, "Illegal character: %c (0x%x)", yytext[0], int(yytext[0]));
|
Error(yylloc, "Illegal character: %c (0x%x)", yytext[0], int(yytext[0]));
|
||||||
YY_USER_ACTION
|
YY_USER_ACTION
|
||||||
}
|
}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
@@ -558,7 +558,7 @@ lParseInteger(bool dotdotdot) {
|
|||||||
else if (*endPtr == 'M')
|
else if (*endPtr == 'M')
|
||||||
mega = true;
|
mega = true;
|
||||||
else if (*endPtr == 'G')
|
else if (*endPtr == 'G')
|
||||||
giga = true;
|
giga = true;
|
||||||
else if (*endPtr == 'l' || *endPtr == 'L')
|
else if (*endPtr == 'l' || *endPtr == 'L')
|
||||||
ls++;
|
ls++;
|
||||||
else if (*endPtr == 'u' || *endPtr == 'U')
|
else if (*endPtr == 'u' || *endPtr == 'U')
|
||||||
@@ -598,7 +598,7 @@ lParseInteger(bool dotdotdot) {
|
|||||||
return TOKEN_UINT64_CONSTANT;
|
return TOKEN_UINT64_CONSTANT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// No u or l suffix
|
// No u or l suffix
|
||||||
// First, see if we can fit this into a 32-bit integer...
|
// First, see if we can fit this into a 32-bit integer...
|
||||||
if (yylval.intVal <= 0x7fffffffULL)
|
if (yylval.intVal <= 0x7fffffffULL)
|
||||||
return TOKEN_INT32_CONSTANT;
|
return TOKEN_INT32_CONSTANT;
|
||||||
@@ -613,7 +613,7 @@ lParseInteger(bool dotdotdot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Handle a C-style comment in the source.
|
/** Handle a C-style comment in the source.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
lCComment(SourcePos *pos) {
|
lCComment(SourcePos *pos) {
|
||||||
@@ -750,7 +750,7 @@ lStringConst(YYSTYPE *yylval, SourcePos *pos)
|
|||||||
char cval = '\0';
|
char cval = '\0';
|
||||||
p = lEscapeChar(p, &cval, pos);
|
p = lEscapeChar(p, &cval, pos);
|
||||||
str.push_back(cval);
|
str.push_back(cval);
|
||||||
}
|
}
|
||||||
yylval->stringVal = new std::string(str);
|
yylval->stringVal = new std::string(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -758,7 +758,7 @@ lStringConst(YYSTYPE *yylval, SourcePos *pos)
|
|||||||
/** Compute the value 2^n, where the exponent is given as an integer.
|
/** Compute the value 2^n, where the exponent is given as an integer.
|
||||||
There are more efficient ways to do this, for example by just slamming
|
There are more efficient ways to do this, for example by just slamming
|
||||||
the bits into the appropriate bits of the double, but let's just do the
|
the bits into the appropriate bits of the double, but let's just do the
|
||||||
obvious thing.
|
obvious thing.
|
||||||
*/
|
*/
|
||||||
static double
|
static double
|
||||||
ipow2(int exponent) {
|
ipow2(int exponent) {
|
||||||
@@ -777,7 +777,7 @@ ipow2(int exponent) {
|
|||||||
|
|
||||||
|
|
||||||
/** Parse a hexadecimal-formatted floating-point number (C99 hex float
|
/** Parse a hexadecimal-formatted floating-point number (C99 hex float
|
||||||
constant-style).
|
constant-style).
|
||||||
*/
|
*/
|
||||||
static double
|
static double
|
||||||
lParseHexFloat(const char *ptr) {
|
lParseHexFloat(const char *ptr) {
|
||||||
|
|||||||
82
llvmutil.cpp
82
llvmutil.cpp
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file llvmutil.cpp
|
/** @file llvmutil.cpp
|
||||||
@@ -124,19 +124,19 @@ InitLLVMUtil(llvm::LLVMContext *ctx, Target target) {
|
|||||||
llvm::VectorType::get(llvm::Type::getInt32Ty(*ctx), target.vectorWidth);
|
llvm::VectorType::get(llvm::Type::getInt32Ty(*ctx), target.vectorWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMTypes::Int1VectorType =
|
LLVMTypes::Int1VectorType =
|
||||||
llvm::VectorType::get(llvm::Type::getInt1Ty(*ctx), target.vectorWidth);
|
llvm::VectorType::get(llvm::Type::getInt1Ty(*ctx), target.vectorWidth);
|
||||||
LLVMTypes::Int8VectorType =
|
LLVMTypes::Int8VectorType =
|
||||||
llvm::VectorType::get(LLVMTypes::Int8Type, target.vectorWidth);
|
llvm::VectorType::get(LLVMTypes::Int8Type, target.vectorWidth);
|
||||||
LLVMTypes::Int16VectorType =
|
LLVMTypes::Int16VectorType =
|
||||||
llvm::VectorType::get(LLVMTypes::Int16Type, target.vectorWidth);
|
llvm::VectorType::get(LLVMTypes::Int16Type, target.vectorWidth);
|
||||||
LLVMTypes::Int32VectorType =
|
LLVMTypes::Int32VectorType =
|
||||||
llvm::VectorType::get(LLVMTypes::Int32Type, target.vectorWidth);
|
llvm::VectorType::get(LLVMTypes::Int32Type, target.vectorWidth);
|
||||||
LLVMTypes::Int64VectorType =
|
LLVMTypes::Int64VectorType =
|
||||||
llvm::VectorType::get(LLVMTypes::Int64Type, target.vectorWidth);
|
llvm::VectorType::get(LLVMTypes::Int64Type, target.vectorWidth);
|
||||||
LLVMTypes::FloatVectorType =
|
LLVMTypes::FloatVectorType =
|
||||||
llvm::VectorType::get(LLVMTypes::FloatType, target.vectorWidth);
|
llvm::VectorType::get(LLVMTypes::FloatType, target.vectorWidth);
|
||||||
LLVMTypes::DoubleVectorType =
|
LLVMTypes::DoubleVectorType =
|
||||||
llvm::VectorType::get(LLVMTypes::DoubleType, target.vectorWidth);
|
llvm::VectorType::get(LLVMTypes::DoubleType, target.vectorWidth);
|
||||||
|
|
||||||
LLVMTypes::Int8VectorPointerType = llvm::PointerType::get(LLVMTypes::Int8VectorType, 0);
|
LLVMTypes::Int8VectorPointerType = llvm::PointerType::get(LLVMTypes::Int8VectorType, 0);
|
||||||
@@ -441,11 +441,11 @@ LLVMUInt64Vector(const uint64_t *ivec) {
|
|||||||
llvm::Constant *
|
llvm::Constant *
|
||||||
LLVMBoolVector(bool b) {
|
LLVMBoolVector(bool b) {
|
||||||
llvm::Constant *v;
|
llvm::Constant *v;
|
||||||
if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
||||||
v = llvm::ConstantInt::get(LLVMTypes::Int32Type, b ? 0xffffffff : 0,
|
v = llvm::ConstantInt::get(LLVMTypes::Int32Type, b ? 0xffffffff : 0,
|
||||||
false /*unsigned*/);
|
false /*unsigned*/);
|
||||||
else {
|
else {
|
||||||
Assert(LLVMTypes::BoolVectorType->getElementType() ==
|
Assert(LLVMTypes::BoolVectorType->getElementType() ==
|
||||||
llvm::Type::getInt1Ty(*g->ctx));
|
llvm::Type::getInt1Ty(*g->ctx));
|
||||||
v = b ? LLVMTrue : LLVMFalse;
|
v = b ? LLVMTrue : LLVMFalse;
|
||||||
}
|
}
|
||||||
@@ -462,11 +462,11 @@ LLVMBoolVector(const bool *bvec) {
|
|||||||
std::vector<llvm::Constant *> vals;
|
std::vector<llvm::Constant *> vals;
|
||||||
for (int i = 0; i < g->target.vectorWidth; ++i) {
|
for (int i = 0; i < g->target.vectorWidth; ++i) {
|
||||||
llvm::Constant *v;
|
llvm::Constant *v;
|
||||||
if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
if (LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
|
||||||
v = llvm::ConstantInt::get(LLVMTypes::Int32Type, bvec[i] ? 0xffffffff : 0,
|
v = llvm::ConstantInt::get(LLVMTypes::Int32Type, bvec[i] ? 0xffffffff : 0,
|
||||||
false /*unsigned*/);
|
false /*unsigned*/);
|
||||||
else {
|
else {
|
||||||
Assert(LLVMTypes::BoolVectorType->getElementType() ==
|
Assert(LLVMTypes::BoolVectorType->getElementType() ==
|
||||||
llvm::Type::getInt1Ty(*g->ctx));
|
llvm::Type::getInt1Ty(*g->ctx));
|
||||||
v = bvec[i] ? LLVMTrue : LLVMFalse;
|
v = bvec[i] ? LLVMTrue : LLVMFalse;
|
||||||
}
|
}
|
||||||
@@ -519,7 +519,7 @@ LLVMUIntAsType(uint64_t val, llvm::Type *type) {
|
|||||||
vectors definitely are equal.
|
vectors definitely are equal.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
lValuesAreEqual(llvm::Value *v0, llvm::Value *v1,
|
lValuesAreEqual(llvm::Value *v0, llvm::Value *v1,
|
||||||
std::vector<llvm::PHINode *> &seenPhi0,
|
std::vector<llvm::PHINode *> &seenPhi0,
|
||||||
std::vector<llvm::PHINode *> &seenPhi1) {
|
std::vector<llvm::PHINode *> &seenPhi1) {
|
||||||
// Thanks to the fact that LLVM hashes and returns the same pointer for
|
// Thanks to the fact that LLVM hashes and returns the same pointer for
|
||||||
@@ -571,7 +571,7 @@ lValuesAreEqual(llvm::Value *v0, llvm::Value *v1,
|
|||||||
// FIXME: should it be ok if the incoming blocks are different,
|
// FIXME: should it be ok if the incoming blocks are different,
|
||||||
// where we just return faliure in this case?
|
// where we just return faliure in this case?
|
||||||
Assert(phi0->getIncomingBlock(i) == phi1->getIncomingBlock(i));
|
Assert(phi0->getIncomingBlock(i) == phi1->getIncomingBlock(i));
|
||||||
if (!lValuesAreEqual(phi0->getIncomingValue(i),
|
if (!lValuesAreEqual(phi0->getIncomingValue(i),
|
||||||
phi1->getIncomingValue(i), seenPhi0, seenPhi1)) {
|
phi1->getIncomingValue(i), seenPhi0, seenPhi1)) {
|
||||||
anyFailure = true;
|
anyFailure = true;
|
||||||
break;
|
break;
|
||||||
@@ -611,7 +611,7 @@ LLVMFlattenInsertChain(llvm::InsertElementInst *ie, int vectorWidth,
|
|||||||
Assert(iOffset >= 0 && iOffset < vectorWidth);
|
Assert(iOffset >= 0 && iOffset < vectorWidth);
|
||||||
Assert(elements[iOffset] == NULL);
|
Assert(elements[iOffset] == NULL);
|
||||||
|
|
||||||
// Get the scalar value from this insert
|
// Get the scalar value from this insert
|
||||||
elements[iOffset] = ie->getOperand(1);
|
elements[iOffset] = ie->getOperand(1);
|
||||||
|
|
||||||
// Do we have another insert?
|
// Do we have another insert?
|
||||||
@@ -623,7 +623,7 @@ LLVMFlattenInsertChain(llvm::InsertElementInst *ie, int vectorWidth,
|
|||||||
|
|
||||||
// Get the value out of a constant vector if that's what we
|
// Get the value out of a constant vector if that's what we
|
||||||
// have
|
// have
|
||||||
llvm::ConstantVector *cv =
|
llvm::ConstantVector *cv =
|
||||||
llvm::dyn_cast<llvm::ConstantVector>(insertBase);
|
llvm::dyn_cast<llvm::ConstantVector>(insertBase);
|
||||||
|
|
||||||
// FIXME: this assert is a little questionable; we probably
|
// FIXME: this assert is a little questionable; we probably
|
||||||
@@ -717,7 +717,7 @@ lIsExactMultiple(llvm::Value *val, int baseValue, int vectorLength,
|
|||||||
// we're good.
|
// we're good.
|
||||||
for (unsigned int i = 0; i < numIncoming; ++i) {
|
for (unsigned int i = 0; i < numIncoming; ++i) {
|
||||||
llvm::Value *incoming = phi->getIncomingValue(i);
|
llvm::Value *incoming = phi->getIncomingValue(i);
|
||||||
bool mult = lIsExactMultiple(incoming, baseValue, vectorLength,
|
bool mult = lIsExactMultiple(incoming, baseValue, vectorLength,
|
||||||
seenPhis);
|
seenPhis);
|
||||||
if (mult == false) {
|
if (mult == false) {
|
||||||
seenPhis.pop_back();
|
seenPhis.pop_back();
|
||||||
@@ -748,9 +748,9 @@ lIsExactMultiple(llvm::Value *val, int baseValue, int vectorLength,
|
|||||||
static int
|
static int
|
||||||
lRoundUpPow2(int v) {
|
lRoundUpPow2(int v) {
|
||||||
v--;
|
v--;
|
||||||
v |= v >> 1;
|
v |= v >> 1;
|
||||||
v |= v >> 2;
|
v |= v >> 2;
|
||||||
v |= v >> 4;
|
v |= v >> 4;
|
||||||
v |= v >> 8;
|
v |= v >> 8;
|
||||||
v |= v >> 16;
|
v |= v >> 16;
|
||||||
return v+1;
|
return v+1;
|
||||||
@@ -804,7 +804,7 @@ lAllDivBaseEqual(llvm::Value *val, int64_t baseValue, int vectorLength,
|
|||||||
for (unsigned int i = 0; i < numIncoming; ++i) {
|
for (unsigned int i = 0; i < numIncoming; ++i) {
|
||||||
llvm::Value *incoming = phi->getIncomingValue(i);
|
llvm::Value *incoming = phi->getIncomingValue(i);
|
||||||
bool ca = canAdd;
|
bool ca = canAdd;
|
||||||
bool mult = lAllDivBaseEqual(incoming, baseValue, vectorLength,
|
bool mult = lAllDivBaseEqual(incoming, baseValue, vectorLength,
|
||||||
seenPhis, ca);
|
seenPhis, ca);
|
||||||
if (mult == false) {
|
if (mult == false) {
|
||||||
seenPhis.pop_back();
|
seenPhis.pop_back();
|
||||||
@@ -816,7 +816,7 @@ lAllDivBaseEqual(llvm::Value *val, int64_t baseValue, int vectorLength,
|
|||||||
}
|
}
|
||||||
|
|
||||||
llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(val);
|
llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(val);
|
||||||
if (bop != NULL && bop->getOpcode() == llvm::Instruction::Add &&
|
if (bop != NULL && bop->getOpcode() == llvm::Instruction::Add &&
|
||||||
canAdd == true) {
|
canAdd == true) {
|
||||||
llvm::Value *op0 = bop->getOperand(0);
|
llvm::Value *op0 = bop->getOperand(0);
|
||||||
llvm::Value *op1 = bop->getOperand(1);
|
llvm::Value *op1 = bop->getOperand(1);
|
||||||
@@ -942,9 +942,9 @@ lVectorValuesAllEqual(llvm::Value *v, int vectorLength,
|
|||||||
llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(v);
|
llvm::BinaryOperator *bop = llvm::dyn_cast<llvm::BinaryOperator>(v);
|
||||||
if (bop != NULL) {
|
if (bop != NULL) {
|
||||||
// Easy case: both operands are all equal -> return true
|
// Easy case: both operands are all equal -> return true
|
||||||
if (lVectorValuesAllEqual(bop->getOperand(0), vectorLength,
|
if (lVectorValuesAllEqual(bop->getOperand(0), vectorLength,
|
||||||
seenPhis) &&
|
seenPhis) &&
|
||||||
lVectorValuesAllEqual(bop->getOperand(1), vectorLength,
|
lVectorValuesAllEqual(bop->getOperand(1), vectorLength,
|
||||||
seenPhis))
|
seenPhis))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -952,7 +952,7 @@ lVectorValuesAllEqual(llvm::Value *v, int vectorLength,
|
|||||||
// high (surviving) bits of the values are equal.
|
// high (surviving) bits of the values are equal.
|
||||||
if (bop->getOpcode() == llvm::Instruction::AShr ||
|
if (bop->getOpcode() == llvm::Instruction::AShr ||
|
||||||
bop->getOpcode() == llvm::Instruction::LShr)
|
bop->getOpcode() == llvm::Instruction::LShr)
|
||||||
return lVectorShiftRightAllEqual(bop->getOperand(0),
|
return lVectorShiftRightAllEqual(bop->getOperand(0),
|
||||||
bop->getOperand(1), vectorLength);
|
bop->getOperand(1), vectorLength);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -960,7 +960,7 @@ lVectorValuesAllEqual(llvm::Value *v, int vectorLength,
|
|||||||
|
|
||||||
llvm::CastInst *cast = llvm::dyn_cast<llvm::CastInst>(v);
|
llvm::CastInst *cast = llvm::dyn_cast<llvm::CastInst>(v);
|
||||||
if (cast != NULL)
|
if (cast != NULL)
|
||||||
return lVectorValuesAllEqual(cast->getOperand(0), vectorLength,
|
return lVectorValuesAllEqual(cast->getOperand(0), vectorLength,
|
||||||
seenPhis);
|
seenPhis);
|
||||||
|
|
||||||
llvm::InsertElementInst *ie = llvm::dyn_cast<llvm::InsertElementInst>(v);
|
llvm::InsertElementInst *ie = llvm::dyn_cast<llvm::InsertElementInst>(v);
|
||||||
@@ -985,7 +985,7 @@ lVectorValuesAllEqual(llvm::Value *v, int vectorLength,
|
|||||||
|
|
||||||
std::vector<llvm::PHINode *> seenPhi0;
|
std::vector<llvm::PHINode *> seenPhi0;
|
||||||
std::vector<llvm::PHINode *> seenPhi1;
|
std::vector<llvm::PHINode *> seenPhi1;
|
||||||
if (lValuesAreEqual(elements[lastNonNull], elements[i], seenPhi0,
|
if (lValuesAreEqual(elements[lastNonNull], elements[i], seenPhi0,
|
||||||
seenPhi1) == false)
|
seenPhi1) == false)
|
||||||
return false;
|
return false;
|
||||||
lastNonNull = i;
|
lastNonNull = i;
|
||||||
@@ -1087,8 +1087,8 @@ lVectorIsLinear(llvm::Value *v, int vectorLength, int stride,
|
|||||||
elements.
|
elements.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
|
lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
|
||||||
int vectorLength,
|
int vectorLength,
|
||||||
int stride) {
|
int stride) {
|
||||||
// Flatten the vector out into the elements array
|
// Flatten the vector out into the elements array
|
||||||
llvm::SmallVector<llvm::Constant *, ISPC_MAX_NVEC> elements;
|
llvm::SmallVector<llvm::Constant *, ISPC_MAX_NVEC> elements;
|
||||||
@@ -1108,7 +1108,7 @@ lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
|
|||||||
// is stride. If not, fail.
|
// is stride. If not, fail.
|
||||||
for (int i = 1; i < vectorLength; ++i) {
|
for (int i = 1; i < vectorLength; ++i) {
|
||||||
ci = llvm::dyn_cast<llvm::ConstantInt>(elements[i]);
|
ci = llvm::dyn_cast<llvm::ConstantInt>(elements[i]);
|
||||||
if (ci == NULL)
|
if (ci == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int64_t nextVal = ci->getSExtValue();
|
int64_t nextVal = ci->getSExtValue();
|
||||||
@@ -1125,7 +1125,7 @@ lVectorIsLinearConstantInts(llvm::ConstantDataVector *cv,
|
|||||||
vector with values that increase by stride.
|
vector with values that increase by stride.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
lCheckMulForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
|
lCheckMulForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
|
||||||
int stride, std::vector<llvm::PHINode *> &seenPhis) {
|
int stride, std::vector<llvm::PHINode *> &seenPhis) {
|
||||||
// Is the first operand a constant integer value splatted across all of
|
// Is the first operand a constant integer value splatted across all of
|
||||||
// the lanes?
|
// the lanes?
|
||||||
@@ -1150,7 +1150,7 @@ lCheckMulForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
|
|||||||
|
|
||||||
// Check to see if the other operand is a linear vector with stride
|
// Check to see if the other operand is a linear vector with stride
|
||||||
// given by stride/splatVal.
|
// given by stride/splatVal.
|
||||||
return lVectorIsLinear(op1, vectorLength, (int)(stride / splatVal),
|
return lVectorIsLinear(op1, vectorLength, (int)(stride / splatVal),
|
||||||
seenPhis);
|
seenPhis);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1161,7 +1161,7 @@ lCheckMulForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
|
|||||||
data.
|
data.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
lCheckAndForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
|
lCheckAndForLinear(llvm::Value *op0, llvm::Value *op1, int vectorLength,
|
||||||
int stride, std::vector<llvm::PHINode *> &seenPhis) {
|
int stride, std::vector<llvm::PHINode *> &seenPhis) {
|
||||||
// Require op1 to be a compile-time constant
|
// Require op1 to be a compile-time constant
|
||||||
int64_t maskValue[ISPC_MAX_NVEC];
|
int64_t maskValue[ISPC_MAX_NVEC];
|
||||||
@@ -1359,7 +1359,7 @@ LLVMDumpValue(llvm::Value *v) {
|
|||||||
|
|
||||||
|
|
||||||
static llvm::Value *
|
static llvm::Value *
|
||||||
lExtractFirstVectorElement(llvm::Value *v,
|
lExtractFirstVectorElement(llvm::Value *v,
|
||||||
std::map<llvm::PHINode *, llvm::PHINode *> &phiMap) {
|
std::map<llvm::PHINode *, llvm::PHINode *> &phiMap) {
|
||||||
llvm::VectorType *vt =
|
llvm::VectorType *vt =
|
||||||
llvm::dyn_cast<llvm::VectorType>(v->getType());
|
llvm::dyn_cast<llvm::VectorType>(v->getType());
|
||||||
@@ -1373,7 +1373,7 @@ lExtractFirstVectorElement(llvm::Value *v,
|
|||||||
if (llvm::ConstantVector *cv = llvm::dyn_cast<llvm::ConstantVector>(v)) {
|
if (llvm::ConstantVector *cv = llvm::dyn_cast<llvm::ConstantVector>(v)) {
|
||||||
return cv->getOperand(0);
|
return cv->getOperand(0);
|
||||||
}
|
}
|
||||||
if (llvm::ConstantDataVector *cdv =
|
if (llvm::ConstantDataVector *cdv =
|
||||||
llvm::dyn_cast<llvm::ConstantDataVector>(v))
|
llvm::dyn_cast<llvm::ConstantDataVector>(v))
|
||||||
return cdv->getElementAsConstant(0);
|
return cdv->getElementAsConstant(0);
|
||||||
|
|
||||||
@@ -1423,9 +1423,9 @@ lExtractFirstVectorElement(llvm::Value *v,
|
|||||||
// The insertion point for the new phi node also has to be the
|
// The insertion point for the new phi node also has to be the
|
||||||
// start of the bblock of the original phi node.
|
// start of the bblock of the original phi node.
|
||||||
llvm::Instruction *phiInsertPos = phi->getParent()->begin();
|
llvm::Instruction *phiInsertPos = phi->getParent()->begin();
|
||||||
llvm::PHINode *scalarPhi =
|
llvm::PHINode *scalarPhi =
|
||||||
llvm::PHINode::Create(vt->getElementType(),
|
llvm::PHINode::Create(vt->getElementType(),
|
||||||
phi->getNumIncomingValues(),
|
phi->getNumIncomingValues(),
|
||||||
newName, phiInsertPos);
|
newName, phiInsertPos);
|
||||||
phiMap[phi] = scalarPhi;
|
phiMap[phi] = scalarPhi;
|
||||||
|
|
||||||
@@ -1452,7 +1452,7 @@ lExtractFirstVectorElement(llvm::Value *v,
|
|||||||
// have here.
|
// have here.
|
||||||
llvm::Instruction *insertAfter = llvm::dyn_cast<llvm::Instruction>(v);
|
llvm::Instruction *insertAfter = llvm::dyn_cast<llvm::Instruction>(v);
|
||||||
Assert(insertAfter != NULL);
|
Assert(insertAfter != NULL);
|
||||||
llvm::Instruction *ee =
|
llvm::Instruction *ee =
|
||||||
llvm::ExtractElementInst::Create(v, LLVMInt32(0), "first_elt",
|
llvm::ExtractElementInst::Create(v, LLVMInt32(0), "first_elt",
|
||||||
(llvm::Instruction *)NULL);
|
(llvm::Instruction *)NULL);
|
||||||
ee->insertAfter(insertAfter);
|
ee->insertAfter(insertAfter);
|
||||||
@@ -1474,7 +1474,7 @@ LLVMExtractFirstVectorElement(llvm::Value *v) {
|
|||||||
vector.
|
vector.
|
||||||
*/
|
*/
|
||||||
llvm::Value *
|
llvm::Value *
|
||||||
LLVMConcatVectors(llvm::Value *v1, llvm::Value *v2,
|
LLVMConcatVectors(llvm::Value *v1, llvm::Value *v2,
|
||||||
llvm::Instruction *insertBefore) {
|
llvm::Instruction *insertBefore) {
|
||||||
Assert(v1->getType() == v2->getType());
|
Assert(v1->getType() == v2->getType());
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file llvmutil.h
|
/** @file llvmutil.h
|
||||||
@@ -59,7 +59,7 @@ namespace llvm {
|
|||||||
/** This structure holds pointers to a variety of LLVM types; code
|
/** This structure holds pointers to a variety of LLVM types; code
|
||||||
elsewhere can use them from here, ratherthan needing to make more
|
elsewhere can use them from here, ratherthan needing to make more
|
||||||
verbose LLVM API calls.
|
verbose LLVM API calls.
|
||||||
*/
|
*/
|
||||||
struct LLVMTypes {
|
struct LLVMTypes {
|
||||||
static llvm::Type *VoidType;
|
static llvm::Type *VoidType;
|
||||||
static llvm::PointerType *VoidPointerType;
|
static llvm::PointerType *VoidPointerType;
|
||||||
@@ -257,7 +257,7 @@ extern bool LLVMExtractVectorInts(llvm::Value *v, int64_t ret[], int *nElts);
|
|||||||
|
|
||||||
and initializes the provided elements array such that the i'th
|
and initializes the provided elements array such that the i'th
|
||||||
llvm::Value * in the array is the element that was inserted into the
|
llvm::Value * in the array is the element that was inserted into the
|
||||||
i'th element of the vector.
|
i'th element of the vector.
|
||||||
|
|
||||||
When the chain of insertelement instruction comes to an end, the only
|
When the chain of insertelement instruction comes to an end, the only
|
||||||
base case that this function handles is the initial value being a
|
base case that this function handles is the initial value being a
|
||||||
@@ -286,7 +286,7 @@ extern llvm::Value *LLVMExtractFirstVectorElement(llvm::Value *v);
|
|||||||
/** This function takes two vectors, expected to be the same length, and
|
/** This function takes two vectors, expected to be the same length, and
|
||||||
returns a new vector of twice the length that represents concatenating
|
returns a new vector of twice the length that represents concatenating
|
||||||
the two of them. */
|
the two of them. */
|
||||||
extern llvm::Value *LLVMConcatVectors(llvm::Value *v1, llvm::Value *v2,
|
extern llvm::Value *LLVMConcatVectors(llvm::Value *v1, llvm::Value *v2,
|
||||||
llvm::Instruction *insertBefore);
|
llvm::Instruction *insertBefore);
|
||||||
|
|
||||||
/** This is a utility function for vector shuffling; it takes two vectors
|
/** This is a utility function for vector shuffling; it takes two vectors
|
||||||
|
|||||||
26
main.cpp
26
main.cpp
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file main.cpp
|
/** @file main.cpp
|
||||||
@@ -60,8 +60,8 @@
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
lPrintVersion() {
|
lPrintVersion() {
|
||||||
printf("Intel(r) SPMD Program Compiler (ispc), %s (build %s @ %s, LLVM %s)\n",
|
printf("Intel(r) SPMD Program Compiler (ispc), %s (build %s @ %s, LLVM %s)\n",
|
||||||
ISPC_VERSION, BUILD_VERSION, BUILD_DATE,
|
ISPC_VERSION, BUILD_VERSION, BUILD_DATE,
|
||||||
#if defined(LLVM_3_1)
|
#if defined(LLVM_3_1)
|
||||||
"3.1"
|
"3.1"
|
||||||
#elif defined(LLVM_3_2)
|
#elif defined(LLVM_3_2)
|
||||||
@@ -70,7 +70,7 @@ lPrintVersion() {
|
|||||||
"3.3"
|
"3.3"
|
||||||
#else
|
#else
|
||||||
#error "Unhandled LLVM version"
|
#error "Unhandled LLVM version"
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ usage(int ret) {
|
|||||||
printf(" [--addressing={32,64}]\t\tSelect 32- or 64-bit addressing. (Note that 32-bit\n");
|
printf(" [--addressing={32,64}]\t\tSelect 32- or 64-bit addressing. (Note that 32-bit\n");
|
||||||
printf(" \t\taddressing calculations are done by default, even\n");
|
printf(" \t\taddressing calculations are done by default, even\n");
|
||||||
printf(" \t\ton 64-bit target architectures.)\n");
|
printf(" \t\ton 64-bit target architectures.)\n");
|
||||||
printf(" [--arch={%s}]\t\tSelect target architecture\n",
|
printf(" [--arch={%s}]\t\tSelect target architecture\n",
|
||||||
Target::SupportedTargetArchs());
|
Target::SupportedTargetArchs());
|
||||||
printf(" [--c++-include-file=<name>]\t\tSpecify name of file to emit in #include statement in generated C++ code.\n");
|
printf(" [--c++-include-file=<name>]\t\tSpecify name of file to emit in #include statement in generated C++ code.\n");
|
||||||
#ifndef ISPC_IS_WINDOWS
|
#ifndef ISPC_IS_WINDOWS
|
||||||
@@ -160,7 +160,7 @@ devUsage(int ret) {
|
|||||||
/** We take arguments from both the command line as well as from the
|
/** We take arguments from both the command line as well as from the
|
||||||
ISPC_ARGS environment variable. This function returns a new set of
|
ISPC_ARGS environment variable. This function returns a new set of
|
||||||
arguments representing the ones from those two sources merged together.
|
arguments representing the ones from those two sources merged together.
|
||||||
*/
|
*/
|
||||||
static void lGetAllArgs(int Argc, char *Argv[], int &argc, char *argv[128]) {
|
static void lGetAllArgs(int Argc, char *Argv[], int &argc, char *argv[128]) {
|
||||||
// Copy over the command line arguments (passed in)
|
// Copy over the command line arguments (passed in)
|
||||||
for (int i = 0; i < Argc; ++i)
|
for (int i = 0; i < Argc; ++i)
|
||||||
@@ -185,7 +185,7 @@ static void lGetAllArgs(int Argc, char *Argv[], int &argc, char *argv[128]) {
|
|||||||
strncpy(ptr, env, len);
|
strncpy(ptr, env, len);
|
||||||
ptr[len] = '\0';
|
ptr[len] = '\0';
|
||||||
|
|
||||||
// Add it to the args array and get out of here
|
// Add it to the args array and get out of here
|
||||||
argv[argc++] = ptr;
|
argv[argc++] = ptr;
|
||||||
if (*end == '\0')
|
if (*end == '\0')
|
||||||
break;
|
break;
|
||||||
@@ -403,7 +403,7 @@ int main(int Argc, char *Argv[]) {
|
|||||||
g->opt.level = 0;
|
g->opt.level = 0;
|
||||||
optSet = true;
|
optSet = true;
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i], "-O") || !strcmp(argv[i], "-O1") ||
|
else if (!strcmp(argv[i], "-O") || !strcmp(argv[i], "-O1") ||
|
||||||
!strcmp(argv[i], "-O2") || !strcmp(argv[i], "-O3")) {
|
!strcmp(argv[i], "-O2") || !strcmp(argv[i], "-O3")) {
|
||||||
g->opt.level = 1;
|
g->opt.level = 1;
|
||||||
optSet = true;
|
optSet = true;
|
||||||
@@ -480,7 +480,7 @@ int main(int Argc, char *Argv[]) {
|
|||||||
int seed = getpid();
|
int seed = getpid();
|
||||||
#endif
|
#endif
|
||||||
g->fuzzTestSeed = seed;
|
g->fuzzTestSeed = seed;
|
||||||
Warning(SourcePos(), "Using seed %d for fuzz testing",
|
Warning(SourcePos(), "Using seed %d for fuzz testing",
|
||||||
g->fuzzTestSeed);
|
g->fuzzTestSeed);
|
||||||
}
|
}
|
||||||
#ifdef ISPC_IS_WINDOWS
|
#ifdef ISPC_IS_WINDOWS
|
||||||
@@ -490,7 +490,7 @@ int main(int Argc, char *Argv[]) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outFileName == NULL &&
|
if (outFileName == NULL &&
|
||||||
headerFileName == NULL &&
|
headerFileName == NULL &&
|
||||||
depsFileName == NULL &&
|
depsFileName == NULL &&
|
||||||
hostStubFileName == NULL &&
|
hostStubFileName == NULL &&
|
||||||
@@ -500,9 +500,9 @@ int main(int Argc, char *Argv[]) {
|
|||||||
"be issued, but no output will be generated.");
|
"be issued, but no output will be generated.");
|
||||||
|
|
||||||
return Module::CompileAndOutput(file, arch, cpu, target, generatePIC,
|
return Module::CompileAndOutput(file, arch, cpu, target, generatePIC,
|
||||||
ot,
|
ot,
|
||||||
outFileName,
|
outFileName,
|
||||||
headerFileName,
|
headerFileName,
|
||||||
includeFileName,
|
includeFileName,
|
||||||
depsFileName,
|
depsFileName,
|
||||||
hostStubFileName,
|
hostStubFileName,
|
||||||
|
|||||||
218
module.cpp
218
module.cpp
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file module.cpp
|
/** @file module.cpp
|
||||||
@@ -163,7 +163,7 @@ lStripUnusedDebugInfo(llvm::Module *module) {
|
|||||||
|
|
||||||
// And now loop over the subprograms inside each compile unit.
|
// And now loop over the subprograms inside each compile unit.
|
||||||
for (unsigned j = 0, je = subprograms.getNumElements(); j != je; ++j) {
|
for (unsigned j = 0, je = subprograms.getNumElements(); j != je; ++j) {
|
||||||
llvm::MDNode *spNode =
|
llvm::MDNode *spNode =
|
||||||
llvm::dyn_cast<llvm::MDNode>(subprograms->getOperand(j));
|
llvm::dyn_cast<llvm::MDNode>(subprograms->getOperand(j));
|
||||||
Assert(spNode != NULL);
|
Assert(spNode != NULL);
|
||||||
llvm::DISubprogram sp(spNode);
|
llvm::DISubprogram sp(spNode);
|
||||||
@@ -197,7 +197,7 @@ lStripUnusedDebugInfo(llvm::Module *module) {
|
|||||||
// debugging metadata organization on the LLVM side changed,
|
// debugging metadata organization on the LLVM side changed,
|
||||||
// here is a bunch of asserting to make sure that element 12 of
|
// here is a bunch of asserting to make sure that element 12 of
|
||||||
// the compile unit's MDNode has the subprograms array....
|
// the compile unit's MDNode has the subprograms array....
|
||||||
llvm::MDNode *nodeSPMD =
|
llvm::MDNode *nodeSPMD =
|
||||||
llvm::dyn_cast<llvm::MDNode>(cuNode->getOperand(12));
|
llvm::dyn_cast<llvm::MDNode>(cuNode->getOperand(12));
|
||||||
Assert(nodeSPMD != NULL);
|
Assert(nodeSPMD != NULL);
|
||||||
llvm::MDNode *nodeSPMDArray =
|
llvm::MDNode *nodeSPMDArray =
|
||||||
@@ -209,9 +209,9 @@ lStripUnusedDebugInfo(llvm::Module *module) {
|
|||||||
|
|
||||||
// And now we can go and stuff it into the node with some
|
// And now we can go and stuff it into the node with some
|
||||||
// confidence...
|
// confidence...
|
||||||
llvm::Value *usedSubprogramsArray =
|
llvm::Value *usedSubprogramsArray =
|
||||||
m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(usedSubprograms));
|
m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(usedSubprograms));
|
||||||
llvm::MDNode *replNode =
|
llvm::MDNode *replNode =
|
||||||
llvm::MDNode::get(*g->ctx, llvm::ArrayRef<llvm::Value *>(usedSubprogramsArray));
|
llvm::MDNode::get(*g->ctx, llvm::ArrayRef<llvm::Value *>(usedSubprogramsArray));
|
||||||
cuNode->replaceOperandWith(12, replNode);
|
cuNode->replaceOperandWith(12, replNode);
|
||||||
}
|
}
|
||||||
@@ -349,7 +349,7 @@ Module::CompileFile() {
|
|||||||
else {
|
else {
|
||||||
// No preprocessor, just open up the file if it's not stdin..
|
// No preprocessor, just open up the file if it's not stdin..
|
||||||
FILE* f = NULL;
|
FILE* f = NULL;
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
f = stdin;
|
f = stdin;
|
||||||
else {
|
else {
|
||||||
f = fopen(filename, "r");
|
f = fopen(filename, "r");
|
||||||
@@ -383,7 +383,7 @@ Module::AddTypeDef(const std::string &name, const Type *type,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initExpr,
|
Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initExpr,
|
||||||
bool isConst, StorageClass storageClass, SourcePos pos) {
|
bool isConst, StorageClass storageClass, SourcePos pos) {
|
||||||
// These may be NULL due to errors in parsing; just gracefully return
|
// These may be NULL due to errors in parsing; just gracefully return
|
||||||
// here if so.
|
// here if so.
|
||||||
@@ -420,7 +420,7 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
|
|||||||
"expression.");
|
"expression.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Type *llvmType = type->LLVMType(g->ctx);
|
llvm::Type *llvmType = type->LLVMType(g->ctx);
|
||||||
if (llvmType == NULL)
|
if (llvmType == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -444,7 +444,7 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
|
|||||||
// convert themselves anyway.)
|
// convert themselves anyway.)
|
||||||
if (dynamic_cast<ExprList *>(initExpr) == NULL)
|
if (dynamic_cast<ExprList *>(initExpr) == NULL)
|
||||||
initExpr = TypeConvertExpr(initExpr, type, "initializer");
|
initExpr = TypeConvertExpr(initExpr, type, "initializer");
|
||||||
|
|
||||||
if (initExpr != NULL) {
|
if (initExpr != NULL) {
|
||||||
initExpr = Optimize(initExpr);
|
initExpr = Optimize(initExpr);
|
||||||
// Fingers crossed, now let's see if we've got a
|
// Fingers crossed, now let's see if we've got a
|
||||||
@@ -481,21 +481,21 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
|
|||||||
|
|
||||||
// If the type doesn't match with the previous one, issue an error.
|
// If the type doesn't match with the previous one, issue an error.
|
||||||
if (!Type::Equal(sym->type, type) ||
|
if (!Type::Equal(sym->type, type) ||
|
||||||
(sym->storageClass != SC_EXTERN &&
|
(sym->storageClass != SC_EXTERN &&
|
||||||
sym->storageClass != SC_EXTERN_C &&
|
sym->storageClass != SC_EXTERN_C &&
|
||||||
sym->storageClass != storageClass)) {
|
sym->storageClass != storageClass)) {
|
||||||
Error(pos, "Definition of variable \"%s\" conflicts with "
|
Error(pos, "Definition of variable \"%s\" conflicts with "
|
||||||
"definition at %s:%d.", name.c_str(),
|
"definition at %s:%d.", name.c_str(),
|
||||||
sym->pos.name, sym->pos.first_line);
|
sym->pos.name, sym->pos.first_line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::GlobalVariable *gv =
|
llvm::GlobalVariable *gv =
|
||||||
llvm::dyn_cast<llvm::GlobalVariable>(sym->storagePtr);
|
llvm::dyn_cast<llvm::GlobalVariable>(sym->storagePtr);
|
||||||
Assert(gv != NULL);
|
Assert(gv != NULL);
|
||||||
|
|
||||||
// And issue an error if this is a redefinition of a variable
|
// And issue an error if this is a redefinition of a variable
|
||||||
if (gv->hasInitializer() &&
|
if (gv->hasInitializer() &&
|
||||||
sym->storageClass != SC_EXTERN && sym->storageClass != SC_EXTERN_C) {
|
sym->storageClass != SC_EXTERN && sym->storageClass != SC_EXTERN_C) {
|
||||||
Error(pos, "Redefinition of variable \"%s\" is illegal. "
|
Error(pos, "Redefinition of variable \"%s\" is illegal. "
|
||||||
"(Previous definition at %s:%d.)", sym->name.c_str(),
|
"(Previous definition at %s:%d.)", sym->name.c_str(),
|
||||||
@@ -521,8 +521,8 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
|
|||||||
// Note that the NULL llvmInitializer is what leads to "extern"
|
// Note that the NULL llvmInitializer is what leads to "extern"
|
||||||
// declarations coming up extern and not defining storage (a bit
|
// declarations coming up extern and not defining storage (a bit
|
||||||
// subtle)...
|
// subtle)...
|
||||||
sym->storagePtr = new llvm::GlobalVariable(*module, llvmType, isConst,
|
sym->storagePtr = new llvm::GlobalVariable(*module, llvmType, isConst,
|
||||||
linkage, llvmInitializer,
|
linkage, llvmInitializer,
|
||||||
sym->name.c_str());
|
sym->name.c_str());
|
||||||
|
|
||||||
// Patch up any references to the previous GlobalVariable (e.g. from a
|
// Patch up any references to the previous GlobalVariable (e.g. from a
|
||||||
@@ -532,11 +532,11 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
|
|||||||
oldGV->removeFromParent();
|
oldGV->removeFromParent();
|
||||||
sym->storagePtr->setName(sym->name.c_str());
|
sym->storagePtr->setName(sym->name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diBuilder) {
|
if (diBuilder) {
|
||||||
llvm::DIFile file = pos.GetDIFile();
|
llvm::DIFile file = pos.GetDIFile();
|
||||||
llvm::DIGlobalVariable var =
|
llvm::DIGlobalVariable var =
|
||||||
diBuilder->createGlobalVariable(name,
|
diBuilder->createGlobalVariable(name,
|
||||||
file,
|
file,
|
||||||
pos.first_line,
|
pos.first_line,
|
||||||
sym->type->GetDIType(file),
|
sym->type->GetDIType(file),
|
||||||
@@ -555,10 +555,10 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
|
|||||||
|
|
||||||
(Note that it's fine for the original struct or a contained struct to
|
(Note that it's fine for the original struct or a contained struct to
|
||||||
be varying, so long as all of its members have bound 'uniform'
|
be varying, so long as all of its members have bound 'uniform'
|
||||||
variability.)
|
variability.)
|
||||||
|
|
||||||
This functions returns true and issues an error if are any illegal
|
This functions returns true and issues an error if are any illegal
|
||||||
types are found and returns false otherwise.
|
types are found and returns false otherwise.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
lRecursiveCheckValidParamType(const Type *t, bool vectorOk) {
|
lRecursiveCheckValidParamType(const Type *t, bool vectorOk) {
|
||||||
@@ -601,7 +601,7 @@ lRecursiveCheckValidParamType(const Type *t, bool vectorOk) {
|
|||||||
varying parameters is illegal.
|
varying parameters is illegal.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
lCheckExportedParameterTypes(const Type *type, const std::string &name,
|
lCheckExportedParameterTypes(const Type *type, const std::string &name,
|
||||||
SourcePos pos) {
|
SourcePos pos) {
|
||||||
if (lRecursiveCheckValidParamType(type, false) == false) {
|
if (lRecursiveCheckValidParamType(type, false) == false) {
|
||||||
if (CastType<PointerType>(type))
|
if (CastType<PointerType>(type))
|
||||||
@@ -645,8 +645,8 @@ lCheckForStructParameters(const FunctionType *ftype, SourcePos pos) {
|
|||||||
false if any errors were encountered.
|
false if any errors were encountered.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Module::AddFunctionDeclaration(const std::string &name,
|
Module::AddFunctionDeclaration(const std::string &name,
|
||||||
const FunctionType *functionType,
|
const FunctionType *functionType,
|
||||||
StorageClass storageClass, bool isInline,
|
StorageClass storageClass, bool isInline,
|
||||||
SourcePos pos) {
|
SourcePos pos) {
|
||||||
Assert(functionType != NULL);
|
Assert(functionType != NULL);
|
||||||
@@ -666,7 +666,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
|||||||
for (unsigned int i = 0; i < overloadFuncs.size(); ++i) {
|
for (unsigned int i = 0; i < overloadFuncs.size(); ++i) {
|
||||||
Symbol *overloadFunc = overloadFuncs[i];
|
Symbol *overloadFunc = overloadFuncs[i];
|
||||||
|
|
||||||
const FunctionType *overloadType =
|
const FunctionType *overloadType =
|
||||||
CastType<FunctionType>(overloadFunc->type);
|
CastType<FunctionType>(overloadFunc->type);
|
||||||
if (overloadType == NULL) {
|
if (overloadType == NULL) {
|
||||||
Assert(m->errorCount == 0);
|
Assert(m->errorCount == 0);
|
||||||
@@ -688,7 +688,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
|||||||
// If all of the parameter types match but the return type is
|
// If all of the parameter types match but the return type is
|
||||||
// different, return an error--overloading by return type isn't
|
// different, return an error--overloading by return type isn't
|
||||||
// allowed.
|
// allowed.
|
||||||
const FunctionType *ofType =
|
const FunctionType *ofType =
|
||||||
CastType<FunctionType>(overloadFunc->type);
|
CastType<FunctionType>(overloadFunc->type);
|
||||||
Assert(ofType != NULL);
|
Assert(ofType != NULL);
|
||||||
if (ofType->GetNumParameters() == functionType->GetNumParameters()) {
|
if (ofType->GetNumParameters() == functionType->GetNumParameters()) {
|
||||||
@@ -725,7 +725,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
|||||||
symbolTable->LookupFunction(name.c_str(), &funcs);
|
symbolTable->LookupFunction(name.c_str(), &funcs);
|
||||||
if (funcs.size() > 0) {
|
if (funcs.size() > 0) {
|
||||||
if (funcs.size() > 1) {
|
if (funcs.size() > 1) {
|
||||||
// Multiple functions with this name have already been declared;
|
// Multiple functions with this name have already been declared;
|
||||||
// can't overload here
|
// can't overload here
|
||||||
Error(pos, "Can't overload extern \"C\" function \"%s\"; "
|
Error(pos, "Can't overload extern \"C\" function \"%s\"; "
|
||||||
"%d functions with the same name have already been declared.",
|
"%d functions with the same name have already been declared.",
|
||||||
@@ -747,7 +747,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
|||||||
|
|
||||||
// Get the LLVM FunctionType
|
// Get the LLVM FunctionType
|
||||||
bool disableMask = (storageClass == SC_EXTERN_C);
|
bool disableMask = (storageClass == SC_EXTERN_C);
|
||||||
llvm::FunctionType *llvmFunctionType =
|
llvm::FunctionType *llvmFunctionType =
|
||||||
functionType->LLVMFunctionType(g->ctx, disableMask);
|
functionType->LLVMFunctionType(g->ctx, disableMask);
|
||||||
if (llvmFunctionType == NULL)
|
if (llvmFunctionType == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -763,13 +763,13 @@ Module::AddFunctionDeclaration(const std::string &name,
|
|||||||
if (g->mangleFunctionsWithTarget)
|
if (g->mangleFunctionsWithTarget)
|
||||||
functionName += g->target.GetISAString();
|
functionName += g->target.GetISAString();
|
||||||
}
|
}
|
||||||
llvm::Function *function =
|
llvm::Function *function =
|
||||||
llvm::Function::Create(llvmFunctionType, linkage, functionName.c_str(),
|
llvm::Function::Create(llvmFunctionType, linkage, functionName.c_str(),
|
||||||
module);
|
module);
|
||||||
|
|
||||||
// Set function attributes: we never throw exceptions
|
// Set function attributes: we never throw exceptions
|
||||||
function->setDoesNotThrow();
|
function->setDoesNotThrow();
|
||||||
if (storageClass != SC_EXTERN_C &&
|
if (storageClass != SC_EXTERN_C &&
|
||||||
!g->generateDebuggingSymbols &&
|
!g->generateDebuggingSymbols &&
|
||||||
isInline)
|
isInline)
|
||||||
#ifdef LLVM_3_2
|
#ifdef LLVM_3_2
|
||||||
@@ -778,7 +778,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
|||||||
function->addFnAttr(llvm::Attribute::AlwaysInline);
|
function->addFnAttr(llvm::Attribute::AlwaysInline);
|
||||||
#endif
|
#endif
|
||||||
if (functionType->isTask)
|
if (functionType->isTask)
|
||||||
// This also applies transitively to members I think?
|
// This also applies transitively to members I think?
|
||||||
#if defined(LLVM_3_1)
|
#if defined(LLVM_3_1)
|
||||||
function->setDoesNotAlias(1, true);
|
function->setDoesNotAlias(1, true);
|
||||||
#else
|
#else
|
||||||
@@ -791,12 +791,12 @@ Module::AddFunctionDeclaration(const std::string &name,
|
|||||||
|
|
||||||
// Make sure that the return type isn't 'varying' or vector typed if
|
// Make sure that the return type isn't 'varying' or vector typed if
|
||||||
// the function is 'export'ed.
|
// the function is 'export'ed.
|
||||||
if (functionType->isExported &&
|
if (functionType->isExported &&
|
||||||
lRecursiveCheckValidParamType(functionType->GetReturnType(), false) == false)
|
lRecursiveCheckValidParamType(functionType->GetReturnType(), false) == false)
|
||||||
Error(pos, "Illegal to return a \"varying\" or vector type from "
|
Error(pos, "Illegal to return a \"varying\" or vector type from "
|
||||||
"exported function \"%s\"", name.c_str());
|
"exported function \"%s\"", name.c_str());
|
||||||
|
|
||||||
if (functionType->isTask &&
|
if (functionType->isTask &&
|
||||||
Type::Equal(functionType->GetReturnType(), AtomicType::Void) == false)
|
Type::Equal(functionType->GetReturnType(), AtomicType::Void) == false)
|
||||||
Error(pos, "Task-qualified functions must have void return type.");
|
Error(pos, "Task-qualified functions must have void return type.");
|
||||||
|
|
||||||
@@ -822,7 +822,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
|||||||
// specify when this is not the case, but this should be the
|
// specify when this is not the case, but this should be the
|
||||||
// default.) Set parameter attributes accordingly. (Only for
|
// default.) Set parameter attributes accordingly. (Only for
|
||||||
// uniform pointers, since varying pointers are int vectors...)
|
// uniform pointers, since varying pointers are int vectors...)
|
||||||
if (!functionType->isTask &&
|
if (!functionType->isTask &&
|
||||||
((CastType<PointerType>(argType) != NULL &&
|
((CastType<PointerType>(argType) != NULL &&
|
||||||
argType->IsUniformType() &&
|
argType->IsUniformType() &&
|
||||||
// Exclude SOA argument because it is a pair {struct *, int}
|
// Exclude SOA argument because it is a pair {struct *, int}
|
||||||
@@ -849,7 +849,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
|||||||
if (symbolTable->LookupFunction(argName.c_str()))
|
if (symbolTable->LookupFunction(argName.c_str()))
|
||||||
Warning(argPos, "Function parameter \"%s\" shadows a function "
|
Warning(argPos, "Function parameter \"%s\" shadows a function "
|
||||||
"declared in global scope.", argName.c_str());
|
"declared in global scope.", argName.c_str());
|
||||||
|
|
||||||
if (defaultValue != NULL)
|
if (defaultValue != NULL)
|
||||||
seenDefaultArg = true;
|
seenDefaultArg = true;
|
||||||
else if (seenDefaultArg) {
|
else if (seenDefaultArg) {
|
||||||
@@ -894,7 +894,7 @@ Module::AddFunctionDefinition(const std::string &name, const FunctionType *type,
|
|||||||
// we need to override the function type here in case the function had
|
// we need to override the function type here in case the function had
|
||||||
// earlier been declared with anonymous parameter names but is now
|
// earlier been declared with anonymous parameter names but is now
|
||||||
// defined with actual names. This is yet another reason we shouldn't
|
// defined with actual names. This is yet another reason we shouldn't
|
||||||
// include the names in FunctionType...
|
// include the names in FunctionType...
|
||||||
sym->type = type;
|
sym->type = type;
|
||||||
|
|
||||||
ast->AddFunction(sym, code);
|
ast->AddFunction(sym, code);
|
||||||
@@ -902,14 +902,14 @@ Module::AddFunctionDefinition(const std::string &name, const FunctionType *type,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Module::AddExportedTypes(const std::vector<std::pair<const Type *,
|
Module::AddExportedTypes(const std::vector<std::pair<const Type *,
|
||||||
SourcePos> > &types) {
|
SourcePos> > &types) {
|
||||||
for (int i = 0; i < (int)types.size(); ++i) {
|
for (int i = 0; i < (int)types.size(); ++i) {
|
||||||
if (CastType<StructType>(types[i].first) == NULL &&
|
if (CastType<StructType>(types[i].first) == NULL &&
|
||||||
CastType<VectorType>(types[i].first) == NULL &&
|
CastType<VectorType>(types[i].first) == NULL &&
|
||||||
CastType<EnumType>(types[i].first) == NULL)
|
CastType<EnumType>(types[i].first) == NULL)
|
||||||
Error(types[i].second, "Only struct, vector, and enum types, "
|
Error(types[i].second, "Only struct, vector, and enum types, "
|
||||||
"not \"%s\", are allowed in type export lists.",
|
"not \"%s\", are allowed in type export lists.",
|
||||||
types[i].first->GetString().c_str());
|
types[i].first->GetString().c_str());
|
||||||
else
|
else
|
||||||
exportedTypes.push_back(types[i]);
|
exportedTypes.push_back(types[i]);
|
||||||
@@ -996,7 +996,7 @@ Module::writeOutput(OutputType outputType, const char *outFileName,
|
|||||||
"C++ emission.");
|
"C++ emission.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
extern bool WriteCXXFile(llvm::Module *module, const char *fn,
|
extern bool WriteCXXFile(llvm::Module *module, const char *fn,
|
||||||
int vectorWidth, const char *includeName);
|
int vectorWidth, const char *includeName);
|
||||||
return WriteCXXFile(module, outFileName, g->target.vectorWidth,
|
return WriteCXXFile(module, outFileName, g->target.vectorWidth,
|
||||||
includeFileName);
|
includeFileName);
|
||||||
@@ -1044,11 +1044,11 @@ Module::writeObjectFileOrAssembly(OutputType outputType, const char *outFileName
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
Module::writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
|
Module::writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
|
||||||
llvm::Module *module, OutputType outputType,
|
llvm::Module *module, OutputType outputType,
|
||||||
const char *outFileName) {
|
const char *outFileName) {
|
||||||
// Figure out if we're generating object file or assembly output, and
|
// Figure out if we're generating object file or assembly output, and
|
||||||
// set binary output for object files
|
// set binary output for object files
|
||||||
llvm::TargetMachine::CodeGenFileType fileType = (outputType == Object) ?
|
llvm::TargetMachine::CodeGenFileType fileType = (outputType == Object) ?
|
||||||
llvm::TargetMachine::CGFT_ObjectFile : llvm::TargetMachine::CGFT_AssemblyFile;
|
llvm::TargetMachine::CGFT_ObjectFile : llvm::TargetMachine::CGFT_AssemblyFile;
|
||||||
bool binary = (fileType == llvm::TargetMachine::CGFT_ObjectFile);
|
bool binary = (fileType == llvm::TargetMachine::CGFT_ObjectFile);
|
||||||
unsigned int flags = binary ? llvm::raw_fd_ostream::F_Binary : 0;
|
unsigned int flags = binary ? llvm::raw_fd_ostream::F_Binary : 0;
|
||||||
@@ -1083,7 +1083,7 @@ Module::writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
|
|||||||
// Finally, run the passes to emit the object file/assembly
|
// Finally, run the passes to emit the object file/assembly
|
||||||
pm.run(*module);
|
pm.run(*module);
|
||||||
|
|
||||||
// Success; tell tool_output_file to keep the final output file.
|
// Success; tell tool_output_file to keep the final output file.
|
||||||
of->keep();
|
of->keep();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1123,7 +1123,7 @@ lEmitStructDecl(const StructType *st, std::vector<const StructType *> *emittedSt
|
|||||||
|
|
||||||
// Otherwise first make sure any contained structs have been declared.
|
// Otherwise first make sure any contained structs have been declared.
|
||||||
for (int i = 0; i < st->GetElementCount(); ++i) {
|
for (int i = 0; i < st->GetElementCount(); ++i) {
|
||||||
const StructType *elementStructType =
|
const StructType *elementStructType =
|
||||||
lGetElementStructType(st->GetElementType(i));
|
lGetElementStructType(st->GetElementType(i));
|
||||||
if (elementStructType != NULL)
|
if (elementStructType != NULL)
|
||||||
lEmitStructDecl(elementStructType, emittedStructs, file);
|
lEmitStructDecl(elementStructType, emittedStructs, file);
|
||||||
@@ -1172,14 +1172,14 @@ lEmitEnumDecls(const std::vector<const EnumType *> &enumTypes, FILE *file) {
|
|||||||
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
|
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
|
||||||
fprintf(file, "// Enumerator types with external visibility from ispc code\n");
|
fprintf(file, "// Enumerator types with external visibility from ispc code\n");
|
||||||
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n\n");
|
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n\n");
|
||||||
|
|
||||||
for (unsigned int i = 0; i < enumTypes.size(); ++i) {
|
for (unsigned int i = 0; i < enumTypes.size(); ++i) {
|
||||||
fprintf(file, "#ifndef __ISPC_ENUM_%s__\n",enumTypes[i]->GetEnumName().c_str());
|
fprintf(file, "#ifndef __ISPC_ENUM_%s__\n",enumTypes[i]->GetEnumName().c_str());
|
||||||
fprintf(file, "#define __ISPC_ENUM_%s__\n",enumTypes[i]->GetEnumName().c_str());
|
fprintf(file, "#define __ISPC_ENUM_%s__\n",enumTypes[i]->GetEnumName().c_str());
|
||||||
std::string declaration = enumTypes[i]->GetCDeclaration("");
|
std::string declaration = enumTypes[i]->GetCDeclaration("");
|
||||||
fprintf(file, "%s {\n", declaration.c_str());
|
fprintf(file, "%s {\n", declaration.c_str());
|
||||||
|
|
||||||
// Print the individual enumerators
|
// Print the individual enumerators
|
||||||
for (int j = 0; j < enumTypes[i]->GetEnumeratorCount(); ++j) {
|
for (int j = 0; j < enumTypes[i]->GetEnumeratorCount(); ++j) {
|
||||||
const Symbol *e = enumTypes[i]->GetEnumerator(j);
|
const Symbol *e = enumTypes[i]->GetEnumerator(j);
|
||||||
Assert(e->constValue != NULL);
|
Assert(e->constValue != NULL);
|
||||||
@@ -1233,7 +1233,7 @@ lEmitVectorTypedefs(const std::vector<const VectorType *> &types, FILE *file) {
|
|||||||
fprintf(file, "struct %s%d { %s v[%d]; };\n", baseDecl.c_str(), size,
|
fprintf(file, "struct %s%d { %s v[%d]; };\n", baseDecl.c_str(), size,
|
||||||
baseDecl.c_str(), size);
|
baseDecl.c_str(), size);
|
||||||
fprintf(file, "#else\n");
|
fprintf(file, "#else\n");
|
||||||
fprintf(file, "struct %s%d { %s v[%d]; } __attribute__ ((aligned(%d)));\n",
|
fprintf(file, "struct %s%d { %s v[%d]; } __attribute__ ((aligned(%d)));\n",
|
||||||
baseDecl.c_str(), size, baseDecl.c_str(), size, align);
|
baseDecl.c_str(), size, baseDecl.c_str(), size, align);
|
||||||
fprintf(file, "#endif\n");
|
fprintf(file, "#endif\n");
|
||||||
fprintf(file, "#endif\n\n");
|
fprintf(file, "#endif\n\n");
|
||||||
@@ -1265,7 +1265,7 @@ lAddTypeIfNew(const Type *type, std::vector<const T *> *exportedTypes) {
|
|||||||
Then, if it's a struct, recursively process its members to do the same.
|
Then, if it's a struct, recursively process its members to do the same.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
lGetExportedTypes(const Type *type,
|
lGetExportedTypes(const Type *type,
|
||||||
std::vector<const StructType *> *exportedStructTypes,
|
std::vector<const StructType *> *exportedStructTypes,
|
||||||
std::vector<const EnumType *> *exportedEnumTypes,
|
std::vector<const EnumType *> *exportedEnumTypes,
|
||||||
std::vector<const VectorType *> *exportedVectorTypes) {
|
std::vector<const VectorType *> *exportedVectorTypes) {
|
||||||
@@ -1273,13 +1273,13 @@ lGetExportedTypes(const Type *type,
|
|||||||
const StructType *structType = CastType<StructType>(type);
|
const StructType *structType = CastType<StructType>(type);
|
||||||
|
|
||||||
if (CastType<ReferenceType>(type) != NULL)
|
if (CastType<ReferenceType>(type) != NULL)
|
||||||
lGetExportedTypes(type->GetReferenceTarget(), exportedStructTypes,
|
lGetExportedTypes(type->GetReferenceTarget(), exportedStructTypes,
|
||||||
exportedEnumTypes, exportedVectorTypes);
|
exportedEnumTypes, exportedVectorTypes);
|
||||||
else if (CastType<PointerType>(type) != NULL)
|
else if (CastType<PointerType>(type) != NULL)
|
||||||
lGetExportedTypes(type->GetBaseType(), exportedStructTypes,
|
lGetExportedTypes(type->GetBaseType(), exportedStructTypes,
|
||||||
exportedEnumTypes, exportedVectorTypes);
|
exportedEnumTypes, exportedVectorTypes);
|
||||||
else if (arrayType != NULL)
|
else if (arrayType != NULL)
|
||||||
lGetExportedTypes(arrayType->GetElementType(), exportedStructTypes,
|
lGetExportedTypes(arrayType->GetElementType(), exportedStructTypes,
|
||||||
exportedEnumTypes, exportedVectorTypes);
|
exportedEnumTypes, exportedVectorTypes);
|
||||||
else if (structType != NULL) {
|
else if (structType != NULL) {
|
||||||
lAddTypeIfNew(type, exportedStructTypes);
|
lAddTypeIfNew(type, exportedStructTypes);
|
||||||
@@ -1303,7 +1303,7 @@ lGetExportedTypes(const Type *type,
|
|||||||
present in the parameters to them.
|
present in the parameters to them.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
lGetExportedParamTypes(const std::vector<Symbol *> &funcs,
|
lGetExportedParamTypes(const std::vector<Symbol *> &funcs,
|
||||||
std::vector<const StructType *> *exportedStructTypes,
|
std::vector<const StructType *> *exportedStructTypes,
|
||||||
std::vector<const EnumType *> *exportedEnumTypes,
|
std::vector<const EnumType *> *exportedEnumTypes,
|
||||||
std::vector<const VectorType *> *exportedVectorTypes) {
|
std::vector<const VectorType *> *exportedVectorTypes) {
|
||||||
@@ -1383,7 +1383,7 @@ std::string emitOffloadParamStruct(const std::string ¶mStructName,
|
|||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
out << "struct " << paramStructName << " {" << std::endl;
|
out << "struct " << paramStructName << " {" << std::endl;
|
||||||
|
|
||||||
for (int i=0;i<fct->GetNumParameters();i++) {
|
for (int i=0;i<fct->GetNumParameters();i++) {
|
||||||
const Type *orgParamType = fct->GetParameterType(i);
|
const Type *orgParamType = fct->GetParameterType(i);
|
||||||
if (orgParamType->IsPointerType() || orgParamType->IsArrayType()) {
|
if (orgParamType->IsPointerType() || orgParamType->IsArrayType()) {
|
||||||
@@ -1405,7 +1405,7 @@ std::string emitOffloadParamStruct(const std::string ¶mStructName,
|
|||||||
}
|
}
|
||||||
std::string paramName = fct->GetParameterName(i);
|
std::string paramName = fct->GetParameterName(i);
|
||||||
std::string paramTypeName = paramType->GetString();
|
std::string paramTypeName = paramType->GetString();
|
||||||
|
|
||||||
std::string tmpArgDecl = paramType->GetCDeclaration(paramName);
|
std::string tmpArgDecl = paramType->GetCDeclaration(paramName);
|
||||||
out << " " << tmpArgDecl << ";" << std::endl;
|
out << " " << tmpArgDecl << ";" << std::endl;
|
||||||
}
|
}
|
||||||
@@ -1415,7 +1415,7 @@ std::string emitOffloadParamStruct(const std::string ¶mStructName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Module::writeDevStub(const char *fn)
|
Module::writeDevStub(const char *fn)
|
||||||
{
|
{
|
||||||
FILE *file = fopen(fn, "w");
|
FILE *file = fopen(fn, "w");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@@ -1427,14 +1427,14 @@ Module::writeDevStub(const char *fn)
|
|||||||
fprintf(file,"#include \"ispc/dev/offload.h\"\n\n");
|
fprintf(file,"#include \"ispc/dev/offload.h\"\n\n");
|
||||||
|
|
||||||
fprintf(file, "#include <stdint.h>\n\n");
|
fprintf(file, "#include <stdint.h>\n\n");
|
||||||
|
|
||||||
// Collect single linear arrays of the *exported* functions (we'll
|
// Collect single linear arrays of the *exported* functions (we'll
|
||||||
// treat those as "__kernel"s in IVL -- "extern" functions will only
|
// treat those as "__kernel"s in IVL -- "extern" functions will only
|
||||||
// be used for dev-dev function calls; only "export" functions will
|
// be used for dev-dev function calls; only "export" functions will
|
||||||
// get exported to the host
|
// get exported to the host
|
||||||
std::vector<Symbol *> exportedFuncs;
|
std::vector<Symbol *> exportedFuncs;
|
||||||
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
|
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
|
||||||
|
|
||||||
// Get all of the struct, vector, and enumerant types used as function
|
// Get all of the struct, vector, and enumerant types used as function
|
||||||
// parameters. These vectors may have repeats.
|
// parameters. These vectors may have repeats.
|
||||||
std::vector<const StructType *> exportedStructTypes;
|
std::vector<const StructType *> exportedStructTypes;
|
||||||
@@ -1442,12 +1442,12 @@ Module::writeDevStub(const char *fn)
|
|||||||
std::vector<const VectorType *> exportedVectorTypes;
|
std::vector<const VectorType *> exportedVectorTypes;
|
||||||
lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
|
lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
|
||||||
&exportedEnumTypes, &exportedVectorTypes);
|
&exportedEnumTypes, &exportedVectorTypes);
|
||||||
|
|
||||||
// And print them
|
// And print them
|
||||||
lEmitVectorTypedefs(exportedVectorTypes, file);
|
lEmitVectorTypedefs(exportedVectorTypes, file);
|
||||||
lEmitEnumDecls(exportedEnumTypes, file);
|
lEmitEnumDecls(exportedEnumTypes, file);
|
||||||
lEmitStructDecls(exportedStructTypes, file);
|
lEmitStructDecls(exportedStructTypes, file);
|
||||||
|
|
||||||
fprintf(file, "#ifdef __cplusplus\n");
|
fprintf(file, "#ifdef __cplusplus\n");
|
||||||
fprintf(file, "namespace ispc {\n");
|
fprintf(file, "namespace ispc {\n");
|
||||||
fprintf(file, "#endif // __cplusplus\n");
|
fprintf(file, "#endif // __cplusplus\n");
|
||||||
@@ -1475,7 +1475,7 @@ Module::writeDevStub(const char *fn)
|
|||||||
Assert(sym);
|
Assert(sym);
|
||||||
const FunctionType *fct = CastType<FunctionType>(sym->type);
|
const FunctionType *fct = CastType<FunctionType>(sym->type);
|
||||||
Assert(fct);
|
Assert(fct);
|
||||||
|
|
||||||
if (!fct->GetReturnType()->IsVoidType()) {
|
if (!fct->GetReturnType()->IsVoidType()) {
|
||||||
//Error(sym->pos,"When emitting offload-stubs, \"export\"ed functions cannot have non-void return types.\n");
|
//Error(sym->pos,"When emitting offload-stubs, \"export\"ed functions cannot have non-void return types.\n");
|
||||||
Warning(sym->pos,"When emitting offload-stubs, ignoring \"export\"ed function with non-void return types.\n");
|
Warning(sym->pos,"When emitting offload-stubs, ignoring \"export\"ed function with non-void return types.\n");
|
||||||
@@ -1505,7 +1505,7 @@ Module::writeDevStub(const char *fn)
|
|||||||
fprintf(file," struct %s args;\n memcpy(&args,in_pMiscData,sizeof(args));\n",
|
fprintf(file," struct %s args;\n memcpy(&args,in_pMiscData,sizeof(args));\n",
|
||||||
paramStructName.c_str());
|
paramStructName.c_str());
|
||||||
std::stringstream funcall;
|
std::stringstream funcall;
|
||||||
|
|
||||||
funcall << "ispc::" << sym->name << "(";
|
funcall << "ispc::" << sym->name << "(";
|
||||||
for (int i=0;i<fct->GetNumParameters();i++) {
|
for (int i=0;i<fct->GetNumParameters();i++) {
|
||||||
// get param type and make it non-const, so we can write while unpacking
|
// get param type and make it non-const, so we can write while unpacking
|
||||||
@@ -1522,7 +1522,7 @@ Module::writeDevStub(const char *fn)
|
|||||||
} else {
|
} else {
|
||||||
paramType = orgParamType->GetAsNonConstType();
|
paramType = orgParamType->GetAsNonConstType();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string paramName = fct->GetParameterName(i);
|
std::string paramName = fct->GetParameterName(i);
|
||||||
std::string paramTypeName = paramType->GetString();
|
std::string paramTypeName = paramType->GetString();
|
||||||
|
|
||||||
@@ -1554,7 +1554,7 @@ Module::writeDevStub(const char *fn)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Module::writeHostStub(const char *fn)
|
Module::writeHostStub(const char *fn)
|
||||||
{
|
{
|
||||||
FILE *file = fopen(fn, "w");
|
FILE *file = fopen(fn, "w");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@@ -1568,14 +1568,14 @@ Module::writeHostStub(const char *fn)
|
|||||||
//fprintf(file,"#ifdef __cplusplus\nextern \"C\" {\n#endif // __cplusplus\n");
|
//fprintf(file,"#ifdef __cplusplus\nextern \"C\" {\n#endif // __cplusplus\n");
|
||||||
|
|
||||||
fprintf(file, "#ifdef __cplusplus\nnamespace ispc {\n#endif // __cplusplus\n\n");
|
fprintf(file, "#ifdef __cplusplus\nnamespace ispc {\n#endif // __cplusplus\n\n");
|
||||||
|
|
||||||
// Collect single linear arrays of the *exported* functions (we'll
|
// Collect single linear arrays of the *exported* functions (we'll
|
||||||
// treat those as "__kernel"s in IVL -- "extern" functions will only
|
// treat those as "__kernel"s in IVL -- "extern" functions will only
|
||||||
// be used for dev-dev function calls; only "export" functions will
|
// be used for dev-dev function calls; only "export" functions will
|
||||||
// get exported to the host
|
// get exported to the host
|
||||||
std::vector<Symbol *> exportedFuncs;
|
std::vector<Symbol *> exportedFuncs;
|
||||||
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
|
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
|
||||||
|
|
||||||
// Get all of the struct, vector, and enumerant types used as function
|
// Get all of the struct, vector, and enumerant types used as function
|
||||||
// parameters. These vectors may have repeats.
|
// parameters. These vectors may have repeats.
|
||||||
std::vector<const StructType *> exportedStructTypes;
|
std::vector<const StructType *> exportedStructTypes;
|
||||||
@@ -1583,12 +1583,12 @@ Module::writeHostStub(const char *fn)
|
|||||||
std::vector<const VectorType *> exportedVectorTypes;
|
std::vector<const VectorType *> exportedVectorTypes;
|
||||||
lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
|
lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
|
||||||
&exportedEnumTypes, &exportedVectorTypes);
|
&exportedEnumTypes, &exportedVectorTypes);
|
||||||
|
|
||||||
// And print them
|
// And print them
|
||||||
lEmitVectorTypedefs(exportedVectorTypes, file);
|
lEmitVectorTypedefs(exportedVectorTypes, file);
|
||||||
lEmitEnumDecls(exportedEnumTypes, file);
|
lEmitEnumDecls(exportedEnumTypes, file);
|
||||||
lEmitStructDecls(exportedStructTypes, file);
|
lEmitStructDecls(exportedStructTypes, file);
|
||||||
|
|
||||||
fprintf(file, "\n");
|
fprintf(file, "\n");
|
||||||
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
|
fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
|
||||||
fprintf(file, "// host-side stubs for dev-side ISPC fucntion(s)\n");
|
fprintf(file, "// host-side stubs for dev-side ISPC fucntion(s)\n");
|
||||||
@@ -1615,7 +1615,7 @@ Module::writeHostStub(const char *fn)
|
|||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
// then, emit a fct stub that unpacks the parameters and pointers
|
// then, emit a fct stub that unpacks the parameters and pointers
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
|
|
||||||
std::string decl = fct->GetCDeclaration(sym->name);
|
std::string decl = fct->GetCDeclaration(sym->name);
|
||||||
fprintf(file, "extern %s {\n", decl.c_str());
|
fprintf(file, "extern %s {\n", decl.c_str());
|
||||||
int numPointers = 0;
|
int numPointers = 0;
|
||||||
@@ -1661,7 +1661,7 @@ Module::writeHostStub(const char *fn)
|
|||||||
numPointers);
|
numPointers);
|
||||||
fprintf(file,"}\n\n");
|
fprintf(file,"}\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// end extern "C"
|
// end extern "C"
|
||||||
fprintf(file, "#ifdef __cplusplus\n");
|
fprintf(file, "#ifdef __cplusplus\n");
|
||||||
fprintf(file, "}/* namespace */\n");
|
fprintf(file, "}/* namespace */\n");
|
||||||
@@ -1669,7 +1669,7 @@ Module::writeHostStub(const char *fn)
|
|||||||
// fprintf(file, "#ifdef __cplusplus\n");
|
// fprintf(file, "#ifdef __cplusplus\n");
|
||||||
// fprintf(file, "}/* end extern C */\n");
|
// fprintf(file, "}/* end extern C */\n");
|
||||||
// fprintf(file, "#endif // __cplusplus\n");
|
// fprintf(file, "#endif // __cplusplus\n");
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1690,9 +1690,9 @@ Module::writeHeader(const char *fn) {
|
|||||||
std::string guard = "ISPC_";
|
std::string guard = "ISPC_";
|
||||||
const char *p = fn;
|
const char *p = fn;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
if (isdigit(*p))
|
if (isdigit(*p))
|
||||||
guard += *p;
|
guard += *p;
|
||||||
else if (isalpha(*p))
|
else if (isalpha(*p))
|
||||||
guard += toupper(*p);
|
guard += toupper(*p);
|
||||||
else
|
else
|
||||||
guard += "_";
|
guard += "_";
|
||||||
@@ -1719,7 +1719,7 @@ Module::writeHeader(const char *fn) {
|
|||||||
std::vector<Symbol *> exportedFuncs, externCFuncs;
|
std::vector<Symbol *> exportedFuncs, externCFuncs;
|
||||||
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
|
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
|
||||||
m->symbolTable->GetMatchingFunctions(lIsExternC, &externCFuncs);
|
m->symbolTable->GetMatchingFunctions(lIsExternC, &externCFuncs);
|
||||||
|
|
||||||
// Get all of the struct, vector, and enumerant types used as function
|
// Get all of the struct, vector, and enumerant types used as function
|
||||||
// parameters. These vectors may have repeats.
|
// parameters. These vectors may have repeats.
|
||||||
std::vector<const StructType *> exportedStructTypes;
|
std::vector<const StructType *> exportedStructTypes;
|
||||||
@@ -1795,10 +1795,10 @@ Module::execPreprocessor(const char *infilename, llvm::raw_string_ostream *ostre
|
|||||||
#endif
|
#endif
|
||||||
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs(new clang::DiagnosticIDs);
|
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs(new clang::DiagnosticIDs);
|
||||||
#if defined(LLVM_3_1)
|
#if defined(LLVM_3_1)
|
||||||
clang::DiagnosticsEngine *diagEngine =
|
clang::DiagnosticsEngine *diagEngine =
|
||||||
new clang::DiagnosticsEngine(diagIDs, diagPrinter);
|
new clang::DiagnosticsEngine(diagIDs, diagPrinter);
|
||||||
#else
|
#else
|
||||||
clang::DiagnosticsEngine *diagEngine =
|
clang::DiagnosticsEngine *diagEngine =
|
||||||
new clang::DiagnosticsEngine(diagIDs, diagOptions, diagPrinter);
|
new clang::DiagnosticsEngine(diagIDs, diagOptions, diagPrinter);
|
||||||
#endif
|
#endif
|
||||||
inst.setDiagnostics(diagEngine);
|
inst.setDiagnostics(diagEngine);
|
||||||
@@ -1843,7 +1843,7 @@ Module::execPreprocessor(const char *infilename, llvm::raw_string_ostream *ostre
|
|||||||
headerOpts.Verbose = 1;
|
headerOpts.Verbose = 1;
|
||||||
for (int i = 0; i < (int)g->includePath.size(); ++i) {
|
for (int i = 0; i < (int)g->includePath.size(); ++i) {
|
||||||
headerOpts.AddPath(g->includePath[i], clang::frontend::Angled,
|
headerOpts.AddPath(g->includePath[i], clang::frontend::Angled,
|
||||||
#if !defined(LLVM_3_3)
|
#if !defined(LLVM_3_3)
|
||||||
true /* is user supplied */,
|
true /* is user supplied */,
|
||||||
#endif
|
#endif
|
||||||
false /* not a framework */,
|
false /* not a framework */,
|
||||||
@@ -1884,7 +1884,7 @@ Module::execPreprocessor(const char *infilename, llvm::raw_string_ostream *ostre
|
|||||||
opts.addMacroDef("ISPC_MINOR_VERSION=3");
|
opts.addMacroDef("ISPC_MINOR_VERSION=3");
|
||||||
|
|
||||||
if (g->includeStdlib) {
|
if (g->includeStdlib) {
|
||||||
if (g->opt.disableAsserts)
|
if (g->opt.disableAsserts)
|
||||||
opts.addMacroDef("assert(x)=");
|
opts.addMacroDef("assert(x)=");
|
||||||
else
|
else
|
||||||
opts.addMacroDef("assert(x)=__assert(#x, x)");
|
opts.addMacroDef("assert(x)=__assert(#x, x)");
|
||||||
@@ -1944,7 +1944,7 @@ lGetTargetFileName(const char *outFileName, const char *isaString) {
|
|||||||
// Given a comma-delimited string with one or more compilation targets of
|
// Given a comma-delimited string with one or more compilation targets of
|
||||||
// the form "sse2,avx-x2", return a vector of strings where each returned
|
// the form "sse2,avx-x2", return a vector of strings where each returned
|
||||||
// string holds one of the targets from the given string.
|
// string holds one of the targets from the given string.
|
||||||
static std::vector<std::string>
|
static std::vector<std::string>
|
||||||
lExtractTargets(const char *target) {
|
lExtractTargets(const char *target) {
|
||||||
std::vector<std::string> targets;
|
std::vector<std::string> targets;
|
||||||
const char *tstart = target;
|
const char *tstart = target;
|
||||||
@@ -1985,14 +1985,14 @@ struct FunctionTargetVariants {
|
|||||||
// Given the symbol table for a module, return a map from function names to
|
// Given the symbol table for a module, return a map from function names to
|
||||||
// FunctionTargetVariants for each function that was defined with the
|
// FunctionTargetVariants for each function that was defined with the
|
||||||
// 'export' qualifier in ispc.
|
// 'export' qualifier in ispc.
|
||||||
static void
|
static void
|
||||||
lGetExportedFunctions(SymbolTable *symbolTable,
|
lGetExportedFunctions(SymbolTable *symbolTable,
|
||||||
std::map<std::string, FunctionTargetVariants> &functions) {
|
std::map<std::string, FunctionTargetVariants> &functions) {
|
||||||
std::vector<Symbol *> syms;
|
std::vector<Symbol *> syms;
|
||||||
symbolTable->GetMatchingFunctions(lSymbolIsExported, &syms);
|
symbolTable->GetMatchingFunctions(lSymbolIsExported, &syms);
|
||||||
for (unsigned int i = 0; i < syms.size(); ++i) {
|
for (unsigned int i = 0; i < syms.size(); ++i) {
|
||||||
FunctionTargetVariants &ftv = functions[syms[i]->name];
|
FunctionTargetVariants &ftv = functions[syms[i]->name];
|
||||||
ftv.func[g->target.isa] = syms[i]->exportedFunction;
|
ftv.func[g->target.isa] = syms[i]->exportedFunction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2016,7 +2016,7 @@ struct RewriteGlobalInfo {
|
|||||||
// multiple definitions of them, one in each of the target-specific output
|
// multiple definitions of them, one in each of the target-specific output
|
||||||
// files.
|
// files.
|
||||||
static void
|
static void
|
||||||
lExtractAndRewriteGlobals(llvm::Module *module,
|
lExtractAndRewriteGlobals(llvm::Module *module,
|
||||||
std::vector<RewriteGlobalInfo> *globals) {
|
std::vector<RewriteGlobalInfo> *globals) {
|
||||||
llvm::Module::global_iterator iter;
|
llvm::Module::global_iterator iter;
|
||||||
for (iter = module->global_begin(); iter != module->global_end(); ++iter) {
|
for (iter = module->global_begin(); iter != module->global_end(); ++iter) {
|
||||||
@@ -2029,7 +2029,7 @@ lExtractAndRewriteGlobals(llvm::Module *module,
|
|||||||
llvm::Constant *init = gv->getInitializer();
|
llvm::Constant *init = gv->getInitializer();
|
||||||
gv->setInitializer(NULL);
|
gv->setInitializer(NULL);
|
||||||
|
|
||||||
Symbol *sym =
|
Symbol *sym =
|
||||||
m->symbolTable->LookupVariable(gv->getName().str().c_str());
|
m->symbolTable->LookupVariable(gv->getName().str().c_str());
|
||||||
Assert(sym != NULL);
|
Assert(sym != NULL);
|
||||||
globals->push_back(RewriteGlobalInfo(gv, init, sym->pos));
|
globals->push_back(RewriteGlobalInfo(gv, init, sym->pos));
|
||||||
@@ -2067,7 +2067,7 @@ lAddExtractedGlobals(llvm::Module *module,
|
|||||||
|
|
||||||
// Create a new global in the given model that matches the original
|
// Create a new global in the given model that matches the original
|
||||||
// global
|
// global
|
||||||
llvm::GlobalVariable *newGlobal =
|
llvm::GlobalVariable *newGlobal =
|
||||||
new llvm::GlobalVariable(*module, type, gv->isConstant(),
|
new llvm::GlobalVariable(*module, type, gv->isConstant(),
|
||||||
llvm::GlobalValue::ExternalLinkage,
|
llvm::GlobalValue::ExternalLinkage,
|
||||||
initializer, gv->getName());
|
initializer, gv->getName());
|
||||||
@@ -2101,7 +2101,7 @@ lAddExtractedGlobals(llvm::Module *module,
|
|||||||
|
|
||||||
|
|
||||||
/** Create the dispatch function for an exported ispc function.
|
/** Create the dispatch function for an exported ispc function.
|
||||||
This function checks to see which vector ISAs the system the
|
This function checks to see which vector ISAs the system the
|
||||||
code is running on supports and calls out to the best available
|
code is running on supports and calls out to the best available
|
||||||
variant that was generated at compile time.
|
variant that was generated at compile time.
|
||||||
|
|
||||||
@@ -2119,7 +2119,7 @@ lAddExtractedGlobals(llvm::Module *module,
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
|
lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
|
||||||
llvm::Value *systemBestISAPtr, const std::string &name,
|
llvm::Value *systemBestISAPtr, const std::string &name,
|
||||||
FunctionTargetVariants &funcs) {
|
FunctionTargetVariants &funcs) {
|
||||||
// The llvm::Function pointers in funcs are pointers to functions in
|
// The llvm::Function pointers in funcs are pointers to functions in
|
||||||
// different llvm::Modules, so we can't call them directly. Therefore,
|
// different llvm::Modules, so we can't call them directly. Therefore,
|
||||||
@@ -2144,18 +2144,18 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
|
|||||||
if (ftype == NULL)
|
if (ftype == NULL)
|
||||||
ftype = funcs.func[i]->getFunctionType();
|
ftype = funcs.func[i]->getFunctionType();
|
||||||
|
|
||||||
targetFuncs[i] =
|
targetFuncs[i] =
|
||||||
llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage,
|
llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage,
|
||||||
funcs.func[i]->getName(), module);
|
funcs.func[i]->getName(), module);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool voidReturn = ftype->getReturnType()->isVoidTy();
|
bool voidReturn = ftype->getReturnType()->isVoidTy();
|
||||||
|
|
||||||
// Now we can emit the definition of the dispatch function..
|
// Now we can emit the definition of the dispatch function..
|
||||||
llvm::Function *dispatchFunc =
|
llvm::Function *dispatchFunc =
|
||||||
llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage,
|
llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage,
|
||||||
name.c_str(), module);
|
name.c_str(), module);
|
||||||
llvm::BasicBlock *bblock =
|
llvm::BasicBlock *bblock =
|
||||||
llvm::BasicBlock::Create(*g->ctx, "entry", dispatchFunc);
|
llvm::BasicBlock::Create(*g->ctx, "entry", dispatchFunc);
|
||||||
|
|
||||||
// Start by calling out to the function that determines the system's
|
// Start by calling out to the function that determines the system's
|
||||||
@@ -2163,7 +2163,7 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
|
|||||||
llvm::CallInst::Create(setISAFunc, "", bblock);
|
llvm::CallInst::Create(setISAFunc, "", bblock);
|
||||||
|
|
||||||
// Now we can load the system's ISA enuemrant
|
// Now we can load the system's ISA enuemrant
|
||||||
llvm::Value *systemISA =
|
llvm::Value *systemISA =
|
||||||
new llvm::LoadInst(systemBestISAPtr, "system_isa", bblock);
|
new llvm::LoadInst(systemBestISAPtr, "system_isa", bblock);
|
||||||
|
|
||||||
// Now emit code that works backwards though the available variants of
|
// Now emit code that works backwards though the available variants of
|
||||||
@@ -2179,12 +2179,12 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
|
|||||||
// Emit code to see if the system can run the current candidate
|
// Emit code to see if the system can run the current candidate
|
||||||
// variant successfully--"is the system's ISA enuemrant value >=
|
// variant successfully--"is the system's ISA enuemrant value >=
|
||||||
// the enumerant value of the current candidate?"
|
// the enumerant value of the current candidate?"
|
||||||
llvm::Value *ok =
|
llvm::Value *ok =
|
||||||
llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGE,
|
llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGE,
|
||||||
systemISA, LLVMInt32(i), "isa_ok", bblock);
|
systemISA, LLVMInt32(i), "isa_ok", bblock);
|
||||||
llvm::BasicBlock *callBBlock =
|
llvm::BasicBlock *callBBlock =
|
||||||
llvm::BasicBlock::Create(*g->ctx, "do_call", dispatchFunc);
|
llvm::BasicBlock::Create(*g->ctx, "do_call", dispatchFunc);
|
||||||
llvm::BasicBlock *nextBBlock =
|
llvm::BasicBlock *nextBBlock =
|
||||||
llvm::BasicBlock::Create(*g->ctx, "next_try", dispatchFunc);
|
llvm::BasicBlock::Create(*g->ctx, "next_try", dispatchFunc);
|
||||||
llvm::BranchInst::Create(callBBlock, nextBBlock, ok, bblock);
|
llvm::BranchInst::Create(callBBlock, nextBBlock, ok, bblock);
|
||||||
|
|
||||||
@@ -2192,7 +2192,7 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
|
|||||||
// Just pass through all of the args from the dispatch function to
|
// Just pass through all of the args from the dispatch function to
|
||||||
// the target-specific function.
|
// the target-specific function.
|
||||||
std::vector<llvm::Value *> args;
|
std::vector<llvm::Value *> args;
|
||||||
llvm::Function::arg_iterator argIter = dispatchFunc->arg_begin();
|
llvm::Function::arg_iterator argIter = dispatchFunc->arg_begin();
|
||||||
for (; argIter != dispatchFunc->arg_end(); ++argIter)
|
for (; argIter != dispatchFunc->arg_end(); ++argIter)
|
||||||
args.push_back(argIter);
|
args.push_back(argIter);
|
||||||
if (voidReturn) {
|
if (voidReturn) {
|
||||||
@@ -2200,8 +2200,8 @@ lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
|
|||||||
llvm::ReturnInst::Create(*g->ctx, callBBlock);
|
llvm::ReturnInst::Create(*g->ctx, callBBlock);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
llvm::Value *retValue =
|
llvm::Value *retValue =
|
||||||
llvm::CallInst::Create(targetFuncs[i], args, "ret_value",
|
llvm::CallInst::Create(targetFuncs[i], args, "ret_value",
|
||||||
callBBlock);
|
callBBlock);
|
||||||
llvm::ReturnInst::Create(*g->ctx, retValue, callBBlock);
|
llvm::ReturnInst::Create(*g->ctx, retValue, callBBlock);
|
||||||
}
|
}
|
||||||
@@ -2244,13 +2244,13 @@ lCreateDispatchModule(std::map<std::string, FunctionTargetVariants> &functions)
|
|||||||
// First, link in the definitions from the builtins-dispatch.ll file.
|
// First, link in the definitions from the builtins-dispatch.ll file.
|
||||||
extern unsigned char builtins_bitcode_dispatch[];
|
extern unsigned char builtins_bitcode_dispatch[];
|
||||||
extern int builtins_bitcode_dispatch_length;
|
extern int builtins_bitcode_dispatch_length;
|
||||||
AddBitcodeToModule(builtins_bitcode_dispatch,
|
AddBitcodeToModule(builtins_bitcode_dispatch,
|
||||||
builtins_bitcode_dispatch_length, module);
|
builtins_bitcode_dispatch_length, module);
|
||||||
|
|
||||||
// Get pointers to things we need below
|
// Get pointers to things we need below
|
||||||
llvm::Function *setFunc = module->getFunction("__set_system_isa");
|
llvm::Function *setFunc = module->getFunction("__set_system_isa");
|
||||||
Assert(setFunc != NULL);
|
Assert(setFunc != NULL);
|
||||||
llvm::Value *systemBestISAPtr =
|
llvm::Value *systemBestISAPtr =
|
||||||
module->getGlobalVariable("__system_best_isa", true);
|
module->getGlobalVariable("__system_best_isa", true);
|
||||||
Assert(systemBestISAPtr != NULL);
|
Assert(systemBestISAPtr != NULL);
|
||||||
|
|
||||||
@@ -2272,18 +2272,18 @@ lCreateDispatchModule(std::map<std::string, FunctionTargetVariants> &functions)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
Module::CompileAndOutput(const char *srcFile,
|
Module::CompileAndOutput(const char *srcFile,
|
||||||
const char *arch,
|
const char *arch,
|
||||||
const char *cpu,
|
const char *cpu,
|
||||||
const char *target,
|
const char *target,
|
||||||
bool generatePIC,
|
bool generatePIC,
|
||||||
OutputType outputType,
|
OutputType outputType,
|
||||||
const char *outFileName,
|
const char *outFileName,
|
||||||
const char *headerFileName,
|
const char *headerFileName,
|
||||||
const char *includeFileName,
|
const char *includeFileName,
|
||||||
const char *depsFileName,
|
const char *depsFileName,
|
||||||
const char *hostStubFileName,
|
const char *hostStubFileName,
|
||||||
const char *devStubFileName)
|
const char *devStubFileName)
|
||||||
{
|
{
|
||||||
if (target == NULL || strchr(target, ',') == NULL) {
|
if (target == NULL || strchr(target, ',') == NULL) {
|
||||||
// We're only compiling to a single target
|
// We're only compiling to a single target
|
||||||
@@ -2368,7 +2368,7 @@ Module::CompileAndOutput(const char *srcFile,
|
|||||||
std::vector<RewriteGlobalInfo> globals[Target::NUM_ISAS];
|
std::vector<RewriteGlobalInfo> globals[Target::NUM_ISAS];
|
||||||
int errorCount = 0;
|
int errorCount = 0;
|
||||||
for (unsigned int i = 0; i < targets.size(); ++i) {
|
for (unsigned int i = 0; i < targets.size(); ++i) {
|
||||||
if (!Target::GetTarget(arch, cpu, targets[i].c_str(), generatePIC,
|
if (!Target::GetTarget(arch, cpu, targets[i].c_str(), generatePIC,
|
||||||
&g->target))
|
&g->target))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@@ -2393,7 +2393,7 @@ Module::CompileAndOutput(const char *srcFile,
|
|||||||
|
|
||||||
if (outFileName != NULL) {
|
if (outFileName != NULL) {
|
||||||
const char *isaName = g->target.GetISAString();
|
const char *isaName = g->target.GetISAString();
|
||||||
std::string targetOutFileName =
|
std::string targetOutFileName =
|
||||||
lGetTargetFileName(outFileName, isaName);
|
lGetTargetFileName(outFileName, isaName);
|
||||||
if (!m->writeOutput(outputType, targetOutFileName.c_str()))
|
if (!m->writeOutput(outputType, targetOutFileName.c_str()))
|
||||||
return 1;
|
return 1;
|
||||||
@@ -2412,7 +2412,7 @@ Module::CompileAndOutput(const char *srcFile,
|
|||||||
// we generate the dispatch module's functions...
|
// we generate the dispatch module's functions...
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Module *dispatchModule =
|
llvm::Module *dispatchModule =
|
||||||
lCreateDispatchModule(exportedFunctions);
|
lCreateDispatchModule(exportedFunctions);
|
||||||
|
|
||||||
lAddExtractedGlobals(dispatchModule, globals);
|
lAddExtractedGlobals(dispatchModule, globals);
|
||||||
@@ -2434,7 +2434,7 @@ Module::CompileAndOutput(const char *srcFile,
|
|||||||
writeObjectFileOrAssembly(firstTargetMachine, dispatchModule,
|
writeObjectFileOrAssembly(firstTargetMachine, dispatchModule,
|
||||||
outputType, outFileName);
|
outputType, outFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorCount > 0;
|
return errorCount > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
module.h
34
module.h
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file module.h
|
/** @file module.h
|
||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
|
|
||||||
/** Add a new global variable corresponding to the given Symbol to the
|
/** Add a new global variable corresponding to the given Symbol to the
|
||||||
module. If non-NULL, initExpr gives the initiailizer expression
|
module. If non-NULL, initExpr gives the initiailizer expression
|
||||||
for the global's inital value. */
|
for the global's inital value. */
|
||||||
void AddGlobalVariable(const std::string &name, const Type *type,
|
void AddGlobalVariable(const std::string &name, const Type *type,
|
||||||
Expr *initExpr, bool isConst,
|
Expr *initExpr, bool isConst,
|
||||||
StorageClass storageClass, SourcePos pos);
|
StorageClass storageClass, SourcePos pos);
|
||||||
@@ -72,7 +72,7 @@ public:
|
|||||||
/** Add a declaration of the function defined by the given function
|
/** Add a declaration of the function defined by the given function
|
||||||
symbol to the module. */
|
symbol to the module. */
|
||||||
void AddFunctionDeclaration(const std::string &name,
|
void AddFunctionDeclaration(const std::string &name,
|
||||||
const FunctionType *ftype,
|
const FunctionType *ftype,
|
||||||
StorageClass sc, bool isInline, SourcePos pos);
|
StorageClass sc, bool isInline, SourcePos pos);
|
||||||
|
|
||||||
/** Adds the function described by the declaration information and the
|
/** Adds the function described by the declaration information and the
|
||||||
@@ -82,7 +82,7 @@ public:
|
|||||||
|
|
||||||
/** Adds the given type to the set of types that have their definitions
|
/** Adds the given type to the set of types that have their definitions
|
||||||
included in automatically generated header files. */
|
included in automatically generated header files. */
|
||||||
void AddExportedTypes(const std::vector<std::pair<const Type *,
|
void AddExportedTypes(const std::vector<std::pair<const Type *,
|
||||||
SourcePos> > &types);
|
SourcePos> > &types);
|
||||||
|
|
||||||
/** After a source file has been compiled, output can be generated in a
|
/** After a source file has been compiled, output can be generated in a
|
||||||
@@ -91,7 +91,7 @@ public:
|
|||||||
Bitcode, /** Generate LLVM IR bitcode output */
|
Bitcode, /** Generate LLVM IR bitcode output */
|
||||||
Object, /** Generate a native object file */
|
Object, /** Generate a native object file */
|
||||||
CXX, /** Generate a C++ file */
|
CXX, /** Generate a C++ file */
|
||||||
Header, /** Generate a C/C++ header file with
|
Header, /** Generate a C/C++ header file with
|
||||||
declarations of 'export'ed functions, global
|
declarations of 'export'ed functions, global
|
||||||
variables, and the types used by them. */
|
variables, and the types used by them. */
|
||||||
Deps, /** generate dependencies */
|
Deps, /** generate dependencies */
|
||||||
@@ -104,14 +104,14 @@ public:
|
|||||||
declarations of functions and types used in the ispc/application
|
declarations of functions and types used in the ispc/application
|
||||||
interface.
|
interface.
|
||||||
@param srcFile Pathname to ispc source file to compile
|
@param srcFile Pathname to ispc source file to compile
|
||||||
@param arch Target architecture (e.g. "x86-64")
|
@param arch %Target architecture (e.g. "x86-64")
|
||||||
@param cpu Target CPU (e.g. "core-i7")
|
@param cpu %Target CPU (e.g. "core-i7")
|
||||||
@param targets Target ISAs; this parameter may give a single target
|
@param targets %Target ISAs; this parameter may give a single target
|
||||||
ISA, or may give a comma-separated list of them in
|
ISA, or may give a comma-separated list of them in
|
||||||
case we are compiling to multiple ISAs.
|
case we are compiling to multiple ISAs.
|
||||||
@param generatePIC Indicates whether position-independent code should
|
@param generatePIC Indicates whether position-independent code should
|
||||||
be generated.
|
be generated.
|
||||||
@param outputType Type of output to generate (object files, assembly,
|
@param outputType %Type of output to generate (object files, assembly,
|
||||||
LLVM bitcode.)
|
LLVM bitcode.)
|
||||||
@param outFileName Base name of output filename for object files, etc.
|
@param outFileName Base name of output filename for object files, etc.
|
||||||
If for example the multiple targets "sse2" and "avx"
|
If for example the multiple targets "sse2" and "avx"
|
||||||
@@ -122,18 +122,18 @@ public:
|
|||||||
inclusion from C/C++ code with declarations of
|
inclusion from C/C++ code with declarations of
|
||||||
types and functions exported from the given ispc
|
types and functions exported from the given ispc
|
||||||
source file.
|
source file.
|
||||||
@param includeFileName If non-NULL, gives the filename for the C++
|
@param includeFileName If non-NULL, gives the filename for the C++
|
||||||
backend to emit in an #include statement to
|
backend to emit in an #include statement to
|
||||||
get definitions of the builtins for the generic
|
get definitions of the builtins for the generic
|
||||||
target.
|
target.
|
||||||
@return Number of errors encountered when compiling
|
@return Number of errors encountered when compiling
|
||||||
srcFile.
|
srcFile.
|
||||||
*/
|
*/
|
||||||
static int CompileAndOutput(const char *srcFile, const char *arch,
|
static int CompileAndOutput(const char *srcFile, const char *arch,
|
||||||
const char *cpu, const char *targets,
|
const char *cpu, const char *targets,
|
||||||
bool generatePIC,
|
bool generatePIC,
|
||||||
OutputType outputType,
|
OutputType outputType,
|
||||||
const char *outFileName,
|
const char *outFileName,
|
||||||
const char *headerFileName,
|
const char *headerFileName,
|
||||||
const char *includeFileName,
|
const char *includeFileName,
|
||||||
const char *depsFileName,
|
const char *depsFileName,
|
||||||
@@ -148,7 +148,7 @@ public:
|
|||||||
SymbolTable *symbolTable;
|
SymbolTable *symbolTable;
|
||||||
|
|
||||||
/** llvm Module object into which globals and functions are added. */
|
/** llvm Module object into which globals and functions are added. */
|
||||||
llvm::Module *module;
|
llvm::Module *module;
|
||||||
|
|
||||||
/** The diBuilder manages generating debugging information */
|
/** The diBuilder manages generating debugging information */
|
||||||
llvm::DIBuilder *diBuilder;
|
llvm::DIBuilder *diBuilder;
|
||||||
@@ -171,7 +171,7 @@ private:
|
|||||||
bool writeHostStub(const char *filename);
|
bool writeHostStub(const char *filename);
|
||||||
bool writeObjectFileOrAssembly(OutputType outputType, const char *filename);
|
bool writeObjectFileOrAssembly(OutputType outputType, const char *filename);
|
||||||
static bool writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
|
static bool writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
|
||||||
llvm::Module *module, OutputType outputType,
|
llvm::Module *module, OutputType outputType,
|
||||||
const char *outFileName);
|
const char *outFileName);
|
||||||
static bool writeBitcode(llvm::Module *module, const char *outFileName);
|
static bool writeBitcode(llvm::Module *module, const char *outFileName);
|
||||||
|
|
||||||
|
|||||||
4
opt.h
4
opt.h
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file opt.h
|
/** @file opt.h
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
/** Optimize the functions in the given module, applying the specified
|
/** Optimize the functions in the given module, applying the specified
|
||||||
level of optimization. optLevel zero corresponds to essentially no
|
level of optimization. optLevel zero corresponds to essentially no
|
||||||
optimization--just enough to generate correct code, while level one
|
optimization--just enough to generate correct code, while level one
|
||||||
corresponds to full optimization.
|
corresponds to full optimization.
|
||||||
*/
|
*/
|
||||||
void Optimize(llvm::Module *module, int optLevel);
|
void Optimize(llvm::Module *module, int optLevel);
|
||||||
|
|
||||||
|
|||||||
228
parse.yy
228
parse.yy
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
%locations
|
%locations
|
||||||
@@ -125,14 +125,14 @@ static const char *lBuiltinTokens[] = {
|
|||||||
"foreach_unique", "goto", "if", "in", "inline",
|
"foreach_unique", "goto", "if", "in", "inline",
|
||||||
"int", "int8", "int16", "int32", "int64", "launch", "new", "NULL",
|
"int", "int8", "int16", "int32", "int64", "launch", "new", "NULL",
|
||||||
"print", "return", "signed", "sizeof", "static", "struct", "switch",
|
"print", "return", "signed", "sizeof", "static", "struct", "switch",
|
||||||
"sync", "task", "true", "typedef", "uniform", "unmasked", "unsigned",
|
"sync", "task", "true", "typedef", "uniform", "unmasked", "unsigned",
|
||||||
"varying", "void", "while", NULL
|
"varying", "void", "while", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *lParamListTokens[] = {
|
static const char *lParamListTokens[] = {
|
||||||
"bool", "const", "double", "enum", "false", "float", "int",
|
"bool", "const", "double", "enum", "false", "float", "int",
|
||||||
"int8", "int16", "int32", "int64", "signed", "struct", "true",
|
"int8", "int16", "int32", "int64", "signed", "struct", "true",
|
||||||
"uniform", "unsigned", "varying", "void", NULL
|
"uniform", "unsigned", "varying", "void", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ForeachDimension {
|
struct ForeachDimension {
|
||||||
@@ -179,27 +179,27 @@ struct ForeachDimension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
%token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT
|
%token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT
|
||||||
%token TOKEN_INT64_CONSTANT TOKEN_UINT64_CONSTANT
|
%token TOKEN_INT64_CONSTANT TOKEN_UINT64_CONSTANT
|
||||||
%token TOKEN_INT32DOTDOTDOT_CONSTANT TOKEN_UINT32DOTDOTDOT_CONSTANT
|
%token TOKEN_INT32DOTDOTDOT_CONSTANT TOKEN_UINT32DOTDOTDOT_CONSTANT
|
||||||
%token TOKEN_INT64DOTDOTDOT_CONSTANT TOKEN_UINT64DOTDOTDOT_CONSTANT
|
%token TOKEN_INT64DOTDOTDOT_CONSTANT TOKEN_UINT64DOTDOTDOT_CONSTANT
|
||||||
%token TOKEN_FLOAT_CONSTANT TOKEN_STRING_C_LITERAL
|
%token TOKEN_FLOAT_CONSTANT TOKEN_STRING_C_LITERAL
|
||||||
%token TOKEN_IDENTIFIER TOKEN_STRING_LITERAL TOKEN_TYPE_NAME TOKEN_NULL
|
%token TOKEN_IDENTIFIER TOKEN_STRING_LITERAL TOKEN_TYPE_NAME TOKEN_NULL
|
||||||
%token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP
|
%token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP
|
||||||
%token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP
|
%token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP
|
||||||
%token TOKEN_AND_OP TOKEN_OR_OP TOKEN_MUL_ASSIGN TOKEN_DIV_ASSIGN TOKEN_MOD_ASSIGN
|
%token TOKEN_AND_OP TOKEN_OR_OP TOKEN_MUL_ASSIGN TOKEN_DIV_ASSIGN TOKEN_MOD_ASSIGN
|
||||||
%token TOKEN_ADD_ASSIGN TOKEN_SUB_ASSIGN TOKEN_LEFT_ASSIGN TOKEN_RIGHT_ASSIGN
|
%token TOKEN_ADD_ASSIGN TOKEN_SUB_ASSIGN TOKEN_LEFT_ASSIGN TOKEN_RIGHT_ASSIGN
|
||||||
%token TOKEN_AND_ASSIGN TOKEN_OR_ASSIGN TOKEN_XOR_ASSIGN
|
%token TOKEN_AND_ASSIGN TOKEN_OR_ASSIGN TOKEN_XOR_ASSIGN
|
||||||
%token TOKEN_SIZEOF TOKEN_NEW TOKEN_DELETE TOKEN_IN
|
%token TOKEN_SIZEOF TOKEN_NEW TOKEN_DELETE TOKEN_IN
|
||||||
|
|
||||||
%token TOKEN_EXTERN TOKEN_EXPORT TOKEN_STATIC TOKEN_INLINE TOKEN_TASK TOKEN_DECLSPEC
|
%token TOKEN_EXTERN TOKEN_EXPORT TOKEN_STATIC TOKEN_INLINE TOKEN_TASK TOKEN_DECLSPEC
|
||||||
%token TOKEN_UNIFORM TOKEN_VARYING TOKEN_TYPEDEF TOKEN_SOA TOKEN_UNMASKED
|
%token TOKEN_UNIFORM TOKEN_VARYING TOKEN_TYPEDEF TOKEN_SOA TOKEN_UNMASKED
|
||||||
%token TOKEN_CHAR TOKEN_INT TOKEN_SIGNED TOKEN_UNSIGNED TOKEN_FLOAT TOKEN_DOUBLE
|
%token TOKEN_CHAR TOKEN_INT TOKEN_SIGNED TOKEN_UNSIGNED TOKEN_FLOAT TOKEN_DOUBLE
|
||||||
%token TOKEN_INT8 TOKEN_INT16 TOKEN_INT64 TOKEN_CONST TOKEN_VOID TOKEN_BOOL
|
%token TOKEN_INT8 TOKEN_INT16 TOKEN_INT64 TOKEN_CONST TOKEN_VOID TOKEN_BOOL
|
||||||
%token TOKEN_ENUM TOKEN_STRUCT TOKEN_TRUE TOKEN_FALSE
|
%token TOKEN_ENUM TOKEN_STRUCT TOKEN_TRUE TOKEN_FALSE
|
||||||
|
|
||||||
%token TOKEN_CASE TOKEN_DEFAULT TOKEN_IF TOKEN_ELSE TOKEN_SWITCH
|
%token TOKEN_CASE TOKEN_DEFAULT TOKEN_IF TOKEN_ELSE TOKEN_SWITCH
|
||||||
%token TOKEN_WHILE TOKEN_DO TOKEN_LAUNCH TOKEN_FOREACH TOKEN_FOREACH_TILED
|
%token TOKEN_WHILE TOKEN_DO TOKEN_LAUNCH TOKEN_FOREACH TOKEN_FOREACH_TILED
|
||||||
%token TOKEN_FOREACH_UNIQUE TOKEN_FOREACH_ACTIVE TOKEN_DOTDOTDOT
|
%token TOKEN_FOREACH_UNIQUE TOKEN_FOREACH_ACTIVE TOKEN_DOTDOTDOT
|
||||||
%token TOKEN_FOR TOKEN_GOTO TOKEN_CONTINUE TOKEN_BREAK TOKEN_RETURN
|
%token TOKEN_FOR TOKEN_GOTO TOKEN_CONTINUE TOKEN_BREAK TOKEN_RETURN
|
||||||
%token TOKEN_CIF TOKEN_CDO TOKEN_CFOR TOKEN_CWHILE
|
%token TOKEN_CIF TOKEN_CDO TOKEN_CFOR TOKEN_CWHILE
|
||||||
@@ -221,7 +221,7 @@ struct ForeachDimension {
|
|||||||
%type <stmt> assert_statement sync_statement delete_statement unmasked_statement
|
%type <stmt> assert_statement sync_statement delete_statement unmasked_statement
|
||||||
|
|
||||||
%type <declaration> declaration parameter_declaration
|
%type <declaration> declaration parameter_declaration
|
||||||
%type <declarators> init_declarator_list
|
%type <declarators> init_declarator_list
|
||||||
%type <declarationList> parameter_list parameter_type_list
|
%type <declarationList> parameter_list parameter_type_list
|
||||||
%type <declarator> declarator pointer reference
|
%type <declarator> declarator pointer reference
|
||||||
%type <declarator> init_declarator direct_declarator struct_declarator
|
%type <declarator> init_declarator direct_declarator struct_declarator
|
||||||
@@ -244,10 +244,10 @@ struct ForeachDimension {
|
|||||||
|
|
||||||
%type <typeQualifier> type_qualifier type_qualifier_list
|
%type <typeQualifier> type_qualifier type_qualifier_list
|
||||||
%type <storageClass> storage_class_specifier
|
%type <storageClass> storage_class_specifier
|
||||||
%type <declSpecs> declaration_specifiers
|
%type <declSpecs> declaration_specifiers
|
||||||
|
|
||||||
%type <stringVal> string_constant
|
%type <stringVal> string_constant
|
||||||
%type <constCharPtr> struct_or_union_name enum_identifier goto_identifier
|
%type <constCharPtr> struct_or_union_name enum_identifier goto_identifier
|
||||||
%type <constCharPtr> foreach_unique_identifier
|
%type <constCharPtr> foreach_unique_identifier
|
||||||
|
|
||||||
%type <intVal> int_constant soa_width_specifier rate_qualified_new
|
%type <intVal> int_constant soa_width_specifier rate_qualified_new
|
||||||
@@ -277,7 +277,7 @@ primary_expression
|
|||||||
Symbol *s = m->symbolTable->LookupVariable(name);
|
Symbol *s = m->symbolTable->LookupVariable(name);
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
if (s)
|
if (s)
|
||||||
$$ = new SymbolExpr(s, @1);
|
$$ = new SymbolExpr(s, @1);
|
||||||
else {
|
else {
|
||||||
std::vector<Symbol *> funs;
|
std::vector<Symbol *> funs;
|
||||||
m->symbolTable->LookupFunction(name, &funs);
|
m->symbolTable->LookupFunction(name, &funs);
|
||||||
@@ -285,7 +285,7 @@ primary_expression
|
|||||||
$$ = new FunctionSymbolExpr(name, funs, @1);
|
$$ = new FunctionSymbolExpr(name, funs, @1);
|
||||||
}
|
}
|
||||||
if ($$ == NULL) {
|
if ($$ == NULL) {
|
||||||
std::vector<std::string> alternates =
|
std::vector<std::string> alternates =
|
||||||
m->symbolTable->ClosestVariableOrFunctionMatch(name);
|
m->symbolTable->ClosestVariableOrFunctionMatch(name);
|
||||||
std::string alts = lGetAlternates(alternates);
|
std::string alts = lGetAlternates(alternates);
|
||||||
Error(@1, "Undeclared symbol \"%s\".%s", name, alts.c_str());
|
Error(@1, "Undeclared symbol \"%s\".%s", name, alts.c_str());
|
||||||
@@ -293,23 +293,23 @@ primary_expression
|
|||||||
}
|
}
|
||||||
| TOKEN_INT32_CONSTANT {
|
| TOKEN_INT32_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
|
$$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
|
||||||
(int32_t)yylval.intVal, @1);
|
(int32_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_UINT32_CONSTANT {
|
| TOKEN_UINT32_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
|
$$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
|
||||||
(uint32_t)yylval.intVal, @1);
|
(uint32_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_INT64_CONSTANT {
|
| TOKEN_INT64_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
|
$$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
|
||||||
(int64_t)yylval.intVal, @1);
|
(int64_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_UINT64_CONSTANT {
|
| TOKEN_UINT64_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
|
$$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
|
||||||
(uint64_t)yylval.intVal, @1);
|
(uint64_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_FLOAT_CONSTANT {
|
| TOKEN_FLOAT_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformFloat->GetAsConstType(),
|
$$ = new ConstExpr(AtomicType::UniformFloat->GetAsConstType(),
|
||||||
(float)yylval.floatVal, @1);
|
(float)yylval.floatVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_TRUE {
|
| TOKEN_TRUE {
|
||||||
$$ = new ConstExpr(AtomicType::UniformBool->GetAsConstType(), true, @1);
|
$$ = new ConstExpr(AtomicType::UniformBool->GetAsConstType(), true, @1);
|
||||||
@@ -328,7 +328,7 @@ primary_expression
|
|||||||
|
|
||||||
launch_expression
|
launch_expression
|
||||||
: TOKEN_LAUNCH postfix_expression '(' argument_expression_list ')'
|
: TOKEN_LAUNCH postfix_expression '(' argument_expression_list ')'
|
||||||
{
|
{
|
||||||
ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @2);
|
ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @2);
|
||||||
$$ = new FunctionCallExpr($2, $4, Union(@2, @5), true, oneExpr);
|
$$ = new FunctionCallExpr($2, $4, Union(@2, @5), true, oneExpr);
|
||||||
}
|
}
|
||||||
@@ -343,7 +343,7 @@ launch_expression
|
|||||||
{ $$ = new FunctionCallExpr($5, new ExprList(Union(@5,@6)), Union(@5,@7), true, $3); }
|
{ $$ = new FunctionCallExpr($5, new ExprList(Union(@5,@6)), Union(@5,@7), true, $3); }
|
||||||
|
|
||||||
| TOKEN_LAUNCH '<' postfix_expression '(' argument_expression_list ')' '>'
|
| TOKEN_LAUNCH '<' postfix_expression '(' argument_expression_list ')' '>'
|
||||||
{
|
{
|
||||||
Error(Union(@2, @7), "\"launch\" expressions no longer take '<' '>' "
|
Error(Union(@2, @7), "\"launch\" expressions no longer take '<' '>' "
|
||||||
"around function call expression.");
|
"around function call expression.");
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
@@ -412,21 +412,21 @@ argument_expression_list
|
|||||||
|
|
||||||
unary_expression
|
unary_expression
|
||||||
: funcall_expression
|
: funcall_expression
|
||||||
| TOKEN_INC_OP unary_expression
|
| TOKEN_INC_OP unary_expression
|
||||||
{ $$ = new UnaryExpr(UnaryExpr::PreInc, $2, Union(@1, @2)); }
|
{ $$ = new UnaryExpr(UnaryExpr::PreInc, $2, Union(@1, @2)); }
|
||||||
| TOKEN_DEC_OP unary_expression
|
| TOKEN_DEC_OP unary_expression
|
||||||
{ $$ = new UnaryExpr(UnaryExpr::PreDec, $2, Union(@1, @2)); }
|
{ $$ = new UnaryExpr(UnaryExpr::PreDec, $2, Union(@1, @2)); }
|
||||||
| '&' unary_expression
|
| '&' unary_expression
|
||||||
{ $$ = new AddressOfExpr($2, Union(@1, @2)); }
|
{ $$ = new AddressOfExpr($2, Union(@1, @2)); }
|
||||||
| '*' unary_expression
|
| '*' unary_expression
|
||||||
{ $$ = new PtrDerefExpr($2, Union(@1, @2)); }
|
{ $$ = new PtrDerefExpr($2, Union(@1, @2)); }
|
||||||
| '+' cast_expression
|
| '+' cast_expression
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
| '-' cast_expression
|
| '-' cast_expression
|
||||||
{ $$ = new UnaryExpr(UnaryExpr::Negate, $2, Union(@1, @2)); }
|
{ $$ = new UnaryExpr(UnaryExpr::Negate, $2, Union(@1, @2)); }
|
||||||
| '~' cast_expression
|
| '~' cast_expression
|
||||||
{ $$ = new UnaryExpr(UnaryExpr::BitNot, $2, Union(@1, @2)); }
|
{ $$ = new UnaryExpr(UnaryExpr::BitNot, $2, Union(@1, @2)); }
|
||||||
| '!' cast_expression
|
| '!' cast_expression
|
||||||
{ $$ = new UnaryExpr(UnaryExpr::LogicalNot, $2, Union(@1, @2)); }
|
{ $$ = new UnaryExpr(UnaryExpr::LogicalNot, $2, Union(@1, @2)); }
|
||||||
| TOKEN_SIZEOF unary_expression
|
| TOKEN_SIZEOF unary_expression
|
||||||
{ $$ = new SizeOfExpr($2, Union(@1, @2)); }
|
{ $$ = new SizeOfExpr($2, Union(@1, @2)); }
|
||||||
@@ -438,7 +438,7 @@ cast_expression
|
|||||||
: unary_expression
|
: unary_expression
|
||||||
| '(' type_name ')' cast_expression
|
| '(' type_name ')' cast_expression
|
||||||
{
|
{
|
||||||
$$ = new TypeCastExpr($2, $4, Union(@1,@4));
|
$$ = new TypeCastExpr($2, $4, Union(@1,@4));
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -630,7 +630,7 @@ constant_expression
|
|||||||
;
|
;
|
||||||
|
|
||||||
declaration_statement
|
declaration_statement
|
||||||
: declaration
|
: declaration
|
||||||
{
|
{
|
||||||
if ($1 == NULL) {
|
if ($1 == NULL) {
|
||||||
AssertPos(@1, m->errorCount > 0);
|
AssertPos(@1, m->errorCount > 0);
|
||||||
@@ -810,11 +810,11 @@ init_declarator_list
|
|||||||
|
|
||||||
init_declarator
|
init_declarator
|
||||||
: declarator
|
: declarator
|
||||||
| declarator '=' initializer
|
| declarator '=' initializer
|
||||||
{
|
{
|
||||||
if ($1 != NULL)
|
if ($1 != NULL)
|
||||||
$1->initExpr = $3;
|
$1->initExpr = $3;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -829,7 +829,7 @@ type_specifier
|
|||||||
: atomic_var_type_specifier { $$ = $1; }
|
: atomic_var_type_specifier { $$ = $1; }
|
||||||
| TOKEN_TYPE_NAME
|
| TOKEN_TYPE_NAME
|
||||||
{
|
{
|
||||||
const Type *t = m->symbolTable->LookupType(yytext);
|
const Type *t = m->symbolTable->LookupType(yytext);
|
||||||
$$ = t;
|
$$ = t;
|
||||||
}
|
}
|
||||||
| struct_or_union_specifier { $$ = $1; }
|
| struct_or_union_specifier { $$ = $1; }
|
||||||
@@ -837,7 +837,7 @@ type_specifier
|
|||||||
;
|
;
|
||||||
|
|
||||||
type_specifier_list
|
type_specifier_list
|
||||||
: type_specifier
|
: type_specifier
|
||||||
{
|
{
|
||||||
if ($1 == NULL)
|
if ($1 == NULL)
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
@@ -883,8 +883,8 @@ struct_or_union_name
|
|||||||
|
|
||||||
struct_or_union_and_name
|
struct_or_union_and_name
|
||||||
: struct_or_union struct_or_union_name
|
: struct_or_union struct_or_union_name
|
||||||
{
|
{
|
||||||
const Type *st = m->symbolTable->LookupType($2);
|
const Type *st = m->symbolTable->LookupType($2);
|
||||||
if (st == NULL) {
|
if (st == NULL) {
|
||||||
st = new UndefinedStructType($2, Variability::Unbound, false, @2);
|
st = new UndefinedStructType($2, Variability::Unbound, false, @2);
|
||||||
m->symbolTable->AddType($2, st, @2);
|
m->symbolTable->AddType($2, st, @2);
|
||||||
@@ -905,7 +905,7 @@ struct_or_union_and_name
|
|||||||
|
|
||||||
struct_or_union_specifier
|
struct_or_union_specifier
|
||||||
: struct_or_union_and_name
|
: struct_or_union_and_name
|
||||||
| struct_or_union_and_name '{' struct_declaration_list '}'
|
| struct_or_union_and_name '{' struct_declaration_list '}'
|
||||||
{
|
{
|
||||||
if ($3 != NULL) {
|
if ($3 != NULL) {
|
||||||
llvm::SmallVector<const Type *, 8> elementTypes;
|
llvm::SmallVector<const Type *, 8> elementTypes;
|
||||||
@@ -924,7 +924,7 @@ struct_or_union_specifier
|
|||||||
else
|
else
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
}
|
}
|
||||||
| struct_or_union '{' struct_declaration_list '}'
|
| struct_or_union '{' struct_declaration_list '}'
|
||||||
{
|
{
|
||||||
if ($3 != NULL) {
|
if ($3 != NULL) {
|
||||||
llvm::SmallVector<const Type *, 8> elementTypes;
|
llvm::SmallVector<const Type *, 8> elementTypes;
|
||||||
@@ -938,7 +938,7 @@ struct_or_union_specifier
|
|||||||
else
|
else
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
}
|
}
|
||||||
| struct_or_union '{' '}'
|
| struct_or_union '{' '}'
|
||||||
{
|
{
|
||||||
llvm::SmallVector<const Type *, 8> elementTypes;
|
llvm::SmallVector<const Type *, 8> elementTypes;
|
||||||
llvm::SmallVector<std::string, 8> elementNames;
|
llvm::SmallVector<std::string, 8> elementNames;
|
||||||
@@ -946,7 +946,7 @@ struct_or_union_specifier
|
|||||||
$$ = new StructType("", elementTypes, elementNames, elementPositions,
|
$$ = new StructType("", elementTypes, elementNames, elementPositions,
|
||||||
false, Variability::Unbound, @1);
|
false, Variability::Unbound, @1);
|
||||||
}
|
}
|
||||||
| struct_or_union_and_name '{' '}'
|
| struct_or_union_and_name '{' '}'
|
||||||
{
|
{
|
||||||
llvm::SmallVector<const Type *, 8> elementTypes;
|
llvm::SmallVector<const Type *, 8> elementTypes;
|
||||||
llvm::SmallVector<std::string, 8> elementNames;
|
llvm::SmallVector<std::string, 8> elementNames;
|
||||||
@@ -963,18 +963,18 @@ struct_or_union_specifier
|
|||||||
;
|
;
|
||||||
|
|
||||||
struct_or_union
|
struct_or_union
|
||||||
: TOKEN_STRUCT
|
: TOKEN_STRUCT
|
||||||
;
|
;
|
||||||
|
|
||||||
struct_declaration_list
|
struct_declaration_list
|
||||||
: struct_declaration
|
: struct_declaration
|
||||||
{
|
{
|
||||||
std::vector<StructDeclaration *> *sdl = new std::vector<StructDeclaration *>;
|
std::vector<StructDeclaration *> *sdl = new std::vector<StructDeclaration *>;
|
||||||
if ($1 != NULL)
|
if ($1 != NULL)
|
||||||
sdl->push_back($1);
|
sdl->push_back($1);
|
||||||
$$ = sdl;
|
$$ = sdl;
|
||||||
}
|
}
|
||||||
| struct_declaration_list struct_declaration
|
| struct_declaration_list struct_declaration
|
||||||
{
|
{
|
||||||
std::vector<StructDeclaration *> *sdl = (std::vector<StructDeclaration *> *)$1;
|
std::vector<StructDeclaration *> *sdl = (std::vector<StructDeclaration *> *)$1;
|
||||||
if (sdl == NULL) {
|
if (sdl == NULL) {
|
||||||
@@ -988,7 +988,7 @@ struct_declaration_list
|
|||||||
;
|
;
|
||||||
|
|
||||||
struct_declaration
|
struct_declaration
|
||||||
: specifier_qualifier_list struct_declarator_list ';'
|
: specifier_qualifier_list struct_declarator_list ';'
|
||||||
{ $$ = ($1 != NULL && $2 != NULL) ? new StructDeclaration($1, $2) : NULL; }
|
{ $$ = ($1 != NULL && $2 != NULL) ? new StructDeclaration($1, $2) : NULL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -996,7 +996,7 @@ specifier_qualifier_list
|
|||||||
: type_specifier specifier_qualifier_list
|
: type_specifier specifier_qualifier_list
|
||||||
| type_specifier
|
| type_specifier
|
||||||
| short_vec_specifier
|
| short_vec_specifier
|
||||||
| type_qualifier specifier_qualifier_list
|
| type_qualifier specifier_qualifier_list
|
||||||
{
|
{
|
||||||
if ($2 != NULL) {
|
if ($2 != NULL) {
|
||||||
if ($1 == TYPEQUAL_UNIFORM) {
|
if ($1 == TYPEQUAL_UNIFORM) {
|
||||||
@@ -1033,7 +1033,7 @@ specifier_qualifier_list
|
|||||||
$2->ResolveUnboundVariability(Variability::Varying)->GetString().c_str());
|
$2->ResolveUnboundVariability(Variability::Varying)->GetString().c_str());
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ($1 == TYPEQUAL_INLINE) {
|
else if ($1 == TYPEQUAL_INLINE) {
|
||||||
Error(@1, "\"inline\" qualifier is illegal outside of "
|
Error(@1, "\"inline\" qualifier is illegal outside of "
|
||||||
"function declarations.");
|
"function declarations.");
|
||||||
@@ -1059,7 +1059,7 @@ specifier_qualifier_list
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (m->errorCount == 0)
|
if (m->errorCount == 0)
|
||||||
Error(@1, "Lost type qualifier in parser.");
|
Error(@1, "Lost type qualifier in parser.");
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1067,14 +1067,14 @@ specifier_qualifier_list
|
|||||||
|
|
||||||
|
|
||||||
struct_declarator_list
|
struct_declarator_list
|
||||||
: struct_declarator
|
: struct_declarator
|
||||||
{
|
{
|
||||||
std::vector<Declarator *> *sdl = new std::vector<Declarator *>;
|
std::vector<Declarator *> *sdl = new std::vector<Declarator *>;
|
||||||
if ($1 != NULL)
|
if ($1 != NULL)
|
||||||
sdl->push_back($1);
|
sdl->push_back($1);
|
||||||
$$ = sdl;
|
$$ = sdl;
|
||||||
}
|
}
|
||||||
| struct_declarator_list ',' struct_declarator
|
| struct_declarator_list ',' struct_declarator
|
||||||
{
|
{
|
||||||
std::vector<Declarator *> *sdl = (std::vector<Declarator *> *)$1;
|
std::vector<Declarator *> *sdl = (std::vector<Declarator *> *)$1;
|
||||||
if (sdl == NULL) {
|
if (sdl == NULL) {
|
||||||
@@ -1099,19 +1099,19 @@ enum_identifier
|
|||||||
: TOKEN_IDENTIFIER { $$ = strdup(yytext); }
|
: TOKEN_IDENTIFIER { $$ = strdup(yytext); }
|
||||||
|
|
||||||
enum_specifier
|
enum_specifier
|
||||||
: TOKEN_ENUM '{' enumerator_list '}'
|
: TOKEN_ENUM '{' enumerator_list '}'
|
||||||
{
|
{
|
||||||
$$ = lCreateEnumType(NULL, $3, @1);
|
$$ = lCreateEnumType(NULL, $3, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_ENUM enum_identifier '{' enumerator_list '}'
|
| TOKEN_ENUM enum_identifier '{' enumerator_list '}'
|
||||||
{
|
{
|
||||||
$$ = lCreateEnumType($2, $4, @2);
|
$$ = lCreateEnumType($2, $4, @2);
|
||||||
}
|
}
|
||||||
| TOKEN_ENUM '{' enumerator_list ',' '}'
|
| TOKEN_ENUM '{' enumerator_list ',' '}'
|
||||||
{
|
{
|
||||||
$$ = lCreateEnumType(NULL, $3, @1);
|
$$ = lCreateEnumType(NULL, $3, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_ENUM enum_identifier '{' enumerator_list ',' '}'
|
| TOKEN_ENUM enum_identifier '{' enumerator_list ',' '}'
|
||||||
{
|
{
|
||||||
$$ = lCreateEnumType($2, $4, @2);
|
$$ = lCreateEnumType($2, $4, @2);
|
||||||
}
|
}
|
||||||
@@ -1138,12 +1138,12 @@ enum_specifier
|
|||||||
;
|
;
|
||||||
|
|
||||||
enumerator_list
|
enumerator_list
|
||||||
: enumerator
|
: enumerator
|
||||||
{
|
{
|
||||||
if ($1 == NULL)
|
if ($1 == NULL)
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
else {
|
else {
|
||||||
std::vector<Symbol *> *el = new std::vector<Symbol *>;
|
std::vector<Symbol *> *el = new std::vector<Symbol *>;
|
||||||
el->push_back($1);
|
el->push_back($1);
|
||||||
$$ = el;
|
$$ = el;
|
||||||
}
|
}
|
||||||
@@ -1198,7 +1198,7 @@ type_qualifier_list
|
|||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| type_qualifier_list type_qualifier
|
| type_qualifier_list type_qualifier
|
||||||
{
|
{
|
||||||
$$ = $1 | $2;
|
$$ = $1 | $2;
|
||||||
}
|
}
|
||||||
@@ -1243,9 +1243,9 @@ direct_declarator
|
|||||||
d->name = yytext;
|
d->name = yytext;
|
||||||
$$ = d;
|
$$ = d;
|
||||||
}
|
}
|
||||||
| '(' declarator ')'
|
| '(' declarator ')'
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
| direct_declarator '[' constant_expression ']'
|
| direct_declarator '[' constant_expression ']'
|
||||||
{
|
{
|
||||||
@@ -1310,9 +1310,9 @@ direct_declarator
|
|||||||
|
|
||||||
|
|
||||||
pointer
|
pointer
|
||||||
: '*'
|
: '*'
|
||||||
{
|
{
|
||||||
$$ = new Declarator(DK_POINTER, @1);
|
$$ = new Declarator(DK_POINTER, @1);
|
||||||
}
|
}
|
||||||
| '*' type_qualifier_list
|
| '*' type_qualifier_list
|
||||||
{
|
{
|
||||||
@@ -1337,9 +1337,9 @@ pointer
|
|||||||
|
|
||||||
|
|
||||||
reference
|
reference
|
||||||
: '&'
|
: '&'
|
||||||
{
|
{
|
||||||
$$ = new Declarator(DK_REFERENCE, @1);
|
$$ = new Declarator(DK_REFERENCE, @1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -1375,10 +1375,10 @@ parameter_list
|
|||||||
parameter_declaration
|
parameter_declaration
|
||||||
: declaration_specifiers declarator
|
: declaration_specifiers declarator
|
||||||
{
|
{
|
||||||
$$ = new Declaration($1, $2);
|
$$ = new Declaration($1, $2);
|
||||||
}
|
}
|
||||||
| declaration_specifiers declarator '=' initializer
|
| declaration_specifiers declarator '=' initializer
|
||||||
{
|
{
|
||||||
if ($1 != NULL && $2 != NULL) {
|
if ($1 != NULL && $2 != NULL) {
|
||||||
$2->initExpr = $4;
|
$2->initExpr = $4;
|
||||||
$$ = new Declaration($1, $2);
|
$$ = new Declaration($1, $2);
|
||||||
@@ -1398,11 +1398,11 @@ parameter_declaration
|
|||||||
if ($1 == NULL)
|
if ($1 == NULL)
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
else
|
else
|
||||||
$$ = new Declaration($1);
|
$$ = new Declaration($1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* K&R?
|
/* K&R?
|
||||||
identifier_list
|
identifier_list
|
||||||
: IDENTIFIER
|
: IDENTIFIER
|
||||||
| identifier_list ',' IDENTIFIER
|
| identifier_list ',' IDENTIFIER
|
||||||
@@ -1588,9 +1588,9 @@ labeled_statement
|
|||||||
$$ = new LabeledStmt($1, $3, @1);
|
$$ = new LabeledStmt($1, $3, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_CASE constant_expression ':' statement
|
| TOKEN_CASE constant_expression ':' statement
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
if ($2 != NULL &&
|
if ($2 != NULL &&
|
||||||
lGetConstantInt($2, &value, @2, "Case statement value")) {
|
lGetConstantInt($2, &value, @2, "Case statement value")) {
|
||||||
$$ = new CaseStmt(value, $4, Union(@1, @2));
|
$$ = new CaseStmt(value, $4, Union(@1, @2));
|
||||||
}
|
}
|
||||||
@@ -1700,19 +1700,19 @@ foreach_active_identifier
|
|||||||
integer_dotdotdot
|
integer_dotdotdot
|
||||||
: TOKEN_INT32DOTDOTDOT_CONSTANT {
|
: TOKEN_INT32DOTDOTDOT_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
|
$$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
|
||||||
(int32_t)yylval.intVal, @1);
|
(int32_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_UINT32DOTDOTDOT_CONSTANT {
|
| TOKEN_UINT32DOTDOTDOT_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
|
$$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
|
||||||
(uint32_t)yylval.intVal, @1);
|
(uint32_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_INT64DOTDOTDOT_CONSTANT {
|
| TOKEN_INT64DOTDOTDOT_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
|
$$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
|
||||||
(int64_t)yylval.intVal, @1);
|
(int64_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_UINT64DOTDOTDOT_CONSTANT {
|
| TOKEN_UINT64DOTDOTDOT_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
|
$$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
|
||||||
(uint64_t)yylval.intVal, @1);
|
(uint64_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -1749,7 +1749,7 @@ foreach_dimension_list
|
|||||||
foreach_unique_scope
|
foreach_unique_scope
|
||||||
: TOKEN_FOREACH_UNIQUE { m->symbolTable->PushScope(); }
|
: TOKEN_FOREACH_UNIQUE { m->symbolTable->PushScope(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
foreach_unique_identifier
|
foreach_unique_identifier
|
||||||
: TOKEN_IDENTIFIER { $$ = yylval.stringVal->c_str(); }
|
: TOKEN_IDENTIFIER { $$ = yylval.stringVal->c_str(); }
|
||||||
;
|
;
|
||||||
@@ -1764,11 +1764,11 @@ iteration_statement
|
|||||||
| TOKEN_CDO statement TOKEN_WHILE '(' expression ')' ';'
|
| TOKEN_CDO statement TOKEN_WHILE '(' expression ')' ';'
|
||||||
{ $$ = new DoStmt($5, $2, true, @1); }
|
{ $$ = new DoStmt($5, $2, true, @1); }
|
||||||
| for_scope '(' for_init_statement for_test ')' statement
|
| for_scope '(' for_init_statement for_test ')' statement
|
||||||
{ $$ = new ForStmt($3, $4, NULL, $6, false, @1);
|
{ $$ = new ForStmt($3, $4, NULL, $6, false, @1);
|
||||||
m->symbolTable->PopScope();
|
m->symbolTable->PopScope();
|
||||||
}
|
}
|
||||||
| for_scope '(' for_init_statement for_test expression ')' statement
|
| for_scope '(' for_init_statement for_test expression ')' statement
|
||||||
{ $$ = new ForStmt($3, $4, new ExprStmt($5, @5), $7, false, @1);
|
{ $$ = new ForStmt($3, $4, new ExprStmt($5, @5), $7, false, @1);
|
||||||
m->symbolTable->PopScope();
|
m->symbolTable->PopScope();
|
||||||
}
|
}
|
||||||
| cfor_scope '(' for_init_statement for_test ')' statement
|
| cfor_scope '(' for_init_statement for_test ')' statement
|
||||||
@@ -1847,7 +1847,7 @@ iteration_statement
|
|||||||
m->symbolTable->PopScope();
|
m->symbolTable->PopScope();
|
||||||
}
|
}
|
||||||
| foreach_unique_scope '(' foreach_unique_identifier TOKEN_IN
|
| foreach_unique_scope '(' foreach_unique_identifier TOKEN_IN
|
||||||
expression ')'
|
expression ')'
|
||||||
{
|
{
|
||||||
Expr *expr = $5;
|
Expr *expr = $5;
|
||||||
const Type *type;
|
const Type *type;
|
||||||
@@ -1905,11 +1905,11 @@ unmasked_statement
|
|||||||
print_statement
|
print_statement
|
||||||
: TOKEN_PRINT '(' string_constant ')' ';'
|
: TOKEN_PRINT '(' string_constant ')' ';'
|
||||||
{
|
{
|
||||||
$$ = new PrintStmt(*$3, NULL, @1);
|
$$ = new PrintStmt(*$3, NULL, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_PRINT '(' string_constant ',' argument_expression_list ')' ';'
|
| TOKEN_PRINT '(' string_constant ',' argument_expression_list ')' ';'
|
||||||
{
|
{
|
||||||
$$ = new PrintStmt(*$3, $5, @1);
|
$$ = new PrintStmt(*$3, $5, @1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -1934,8 +1934,8 @@ external_declaration
|
|||||||
if ($3 != NULL)
|
if ($3 != NULL)
|
||||||
m->AddExportedTypes(*$3);
|
m->AddExportedTypes(*$3);
|
||||||
}
|
}
|
||||||
| declaration
|
| declaration
|
||||||
{
|
{
|
||||||
if ($1 != NULL)
|
if ($1 != NULL)
|
||||||
for (unsigned int i = 0; i < $1->declarators.size(); ++i)
|
for (unsigned int i = 0; i < $1->declarators.size(); ++i)
|
||||||
lAddDeclaration($1->declSpecs, $1->declarators[i]);
|
lAddDeclaration($1->declSpecs, $1->declarators[i]);
|
||||||
@@ -1944,14 +1944,14 @@ external_declaration
|
|||||||
;
|
;
|
||||||
|
|
||||||
function_definition
|
function_definition
|
||||||
: declaration_specifiers declarator
|
: declaration_specifiers declarator
|
||||||
{
|
{
|
||||||
lAddDeclaration($1, $2);
|
lAddDeclaration($1, $2);
|
||||||
lAddFunctionParams($2);
|
lAddFunctionParams($2);
|
||||||
lAddMaskToSymbolTable(@2);
|
lAddMaskToSymbolTable(@2);
|
||||||
if ($1->typeQualifiers & TYPEQUAL_TASK)
|
if ($1->typeQualifiers & TYPEQUAL_TASK)
|
||||||
lAddThreadIndexCountToSymbolTable(@2);
|
lAddThreadIndexCountToSymbolTable(@2);
|
||||||
}
|
}
|
||||||
compound_statement
|
compound_statement
|
||||||
{
|
{
|
||||||
if ($2 != NULL) {
|
if ($2 != NULL) {
|
||||||
@@ -1970,7 +1970,7 @@ function_definition
|
|||||||
m->symbolTable->PopScope(); // push in lAddFunctionParams();
|
m->symbolTable->PopScope(); // push in lAddFunctionParams();
|
||||||
}
|
}
|
||||||
/* function with no declared return type??
|
/* function with no declared return type??
|
||||||
func(...)
|
func(...)
|
||||||
| declarator { lAddFunctionParams($1); } compound_statement
|
| declarator { lAddFunctionParams($1); } compound_statement
|
||||||
{
|
{
|
||||||
m->AddFunction(new DeclSpecs(XXX, $1, $3);
|
m->AddFunction(new DeclSpecs(XXX, $1, $3);
|
||||||
@@ -2002,34 +2002,34 @@ lYYTNameErr (char *yyres, const char *yystr)
|
|||||||
else
|
else
|
||||||
return yystpcpy(yyres, n.c_str()) - yyres;
|
return yystpcpy(yyres, n.c_str()) - yyres;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*yystr == '"')
|
if (*yystr == '"')
|
||||||
{
|
{
|
||||||
YYSIZE_T yyn = 0;
|
YYSIZE_T yyn = 0;
|
||||||
char const *yyp = yystr;
|
char const *yyp = yystr;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
switch (*++yyp)
|
switch (*++yyp)
|
||||||
{
|
{
|
||||||
case '\'':
|
case '\'':
|
||||||
case ',':
|
case ',':
|
||||||
goto do_not_strip_quotes;
|
goto do_not_strip_quotes;
|
||||||
|
|
||||||
case '\\':
|
case '\\':
|
||||||
if (*++yyp != '\\')
|
if (*++yyp != '\\')
|
||||||
goto do_not_strip_quotes;
|
goto do_not_strip_quotes;
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
default:
|
default:
|
||||||
if (yyres)
|
if (yyres)
|
||||||
yyres[yyn] = *yyp;
|
yyres[yyn] = *yyp;
|
||||||
yyn++;
|
yyn++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '"':
|
case '"':
|
||||||
if (yyres)
|
if (yyres)
|
||||||
yyres[yyn] = '\0';
|
yyres[yyn] = '\0';
|
||||||
return yyn;
|
return yyn;
|
||||||
}
|
}
|
||||||
do_not_strip_quotes: ;
|
do_not_strip_quotes: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2085,7 +2085,7 @@ lAddDeclaration(DeclSpecs *ds, Declarator *decl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
decl->type = decl->type->ResolveUnboundVariability(Variability::Varying);
|
decl->type = decl->type->ResolveUnboundVariability(Variability::Varying);
|
||||||
|
|
||||||
const FunctionType *ft = CastType<FunctionType>(decl->type);
|
const FunctionType *ft = CastType<FunctionType>(decl->type);
|
||||||
if (ft != NULL) {
|
if (ft != NULL) {
|
||||||
bool isInline = (ds->typeQualifiers & TYPEQUAL_INLINE);
|
bool isInline = (ds->typeQualifiers & TYPEQUAL_INLINE);
|
||||||
@@ -2113,7 +2113,7 @@ lAddFunctionParams(Declarator *decl) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// walk down to the declarator for the function itself
|
// walk down to the declarator for the function itself
|
||||||
while (decl->kind != DK_FUNCTION && decl->child != NULL)
|
while (decl->kind != DK_FUNCTION && decl->child != NULL)
|
||||||
decl = decl->child;
|
decl = decl->child;
|
||||||
if (decl->kind != DK_FUNCTION) {
|
if (decl->kind != DK_FUNCTION) {
|
||||||
@@ -2265,13 +2265,13 @@ lCreateEnumType(const char *name, std::vector<Symbol *> *enums, SourcePos pos) {
|
|||||||
|
|
||||||
|
|
||||||
/** Given an array of enumerator symbols, make sure each of them has a
|
/** Given an array of enumerator symbols, make sure each of them has a
|
||||||
ConstExpr * in their Symbol::constValue member that stores their
|
ConstExpr * in their Symbol::constValue member that stores their
|
||||||
unsigned integer value. Symbols that had values explicitly provided
|
unsigned integer value. Symbols that had values explicitly provided
|
||||||
in the source file will already have ConstExpr * set; we just need
|
in the source file will already have ConstExpr * set; we just need
|
||||||
to set the values for the others here.
|
to set the values for the others here.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
|
lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
|
||||||
const EnumType *enumType) {
|
const EnumType *enumType) {
|
||||||
enumType = enumType->GetAsConstType();
|
enumType = enumType->GetAsConstType();
|
||||||
enumType = enumType->GetAsUniformType();
|
enumType = enumType->GetAsUniformType();
|
||||||
@@ -2304,7 +2304,7 @@ lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
|
|||||||
AssertPos(enums[i]->pos, enums[i]->constValue != NULL);
|
AssertPos(enums[i]->pos, enums[i]->constValue != NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
enums[i]->constValue = new ConstExpr(enumType, nextVal++,
|
enums[i]->constValue = new ConstExpr(enumType, nextVal++,
|
||||||
enums[i]->pos);
|
enums[i]->pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
294
stmt.cpp
294
stmt.cpp
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file stmt.cpp
|
/** @file stmt.cpp
|
||||||
@@ -81,18 +81,18 @@ Stmt::Optimize() {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// ExprStmt
|
// ExprStmt
|
||||||
|
|
||||||
ExprStmt::ExprStmt(Expr *e, SourcePos p)
|
ExprStmt::ExprStmt(Expr *e, SourcePos p)
|
||||||
: Stmt(p) {
|
: Stmt(p) {
|
||||||
expr = e;
|
expr = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExprStmt::EmitCode(FunctionEmitContext *ctx) const {
|
ExprStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctx->SetDebugPos(pos);
|
ctx->SetDebugPos(pos);
|
||||||
if (expr)
|
if (expr)
|
||||||
expr->GetValue(ctx);
|
expr->GetValue(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ ExprStmt::TypeCheck() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
ExprStmt::Print(int indent) const {
|
ExprStmt::Print(int indent) const {
|
||||||
if (!expr)
|
if (!expr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
printf("%*c", indent, ' ');
|
printf("%*c", indent, ' ');
|
||||||
@@ -141,11 +141,11 @@ lHasUnsizedArrays(const Type *type) {
|
|||||||
else
|
else
|
||||||
return lHasUnsizedArrays(at->GetElementType());
|
return lHasUnsizedArrays(at->GetElementType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DeclStmt::EmitCode(FunctionEmitContext *ctx) const {
|
DeclStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < vars.size(); ++i) {
|
for (unsigned int i = 0; i < vars.size(); ++i) {
|
||||||
@@ -236,13 +236,13 @@ DeclStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// Allocate space for the static variable in global scope, so
|
// Allocate space for the static variable in global scope, so
|
||||||
// that it persists across function calls
|
// that it persists across function calls
|
||||||
sym->storagePtr =
|
sym->storagePtr =
|
||||||
new llvm::GlobalVariable(*m->module, llvmType,
|
new llvm::GlobalVariable(*m->module, llvmType,
|
||||||
sym->type->IsConstType(),
|
sym->type->IsConstType(),
|
||||||
llvm::GlobalValue::InternalLinkage, cinit,
|
llvm::GlobalValue::InternalLinkage, cinit,
|
||||||
llvm::Twine("static.") +
|
llvm::Twine("static.") +
|
||||||
llvm::Twine(sym->pos.first_line) +
|
llvm::Twine(sym->pos.first_line) +
|
||||||
llvm::Twine(".") + sym->name.c_str());
|
llvm::Twine(".") + sym->name.c_str());
|
||||||
// Tell the FunctionEmitContext about the variable
|
// Tell the FunctionEmitContext about the variable
|
||||||
ctx->EmitVariableDebugInfo(sym);
|
ctx->EmitVariableDebugInfo(sym);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -282,7 +282,7 @@ DeclStmt::Optimize() {
|
|||||||
// computing array sizes from non-trivial expressions is
|
// computing array sizes from non-trivial expressions is
|
||||||
// consequently limited.
|
// consequently limited.
|
||||||
Symbol *sym = vars[i].sym;
|
Symbol *sym = vars[i].sym;
|
||||||
if (sym->type && sym->type->IsConstType() &&
|
if (sym->type && sym->type->IsConstType() &&
|
||||||
Type::Equal(init->GetType(), sym->type))
|
Type::Equal(init->GetType(), sym->type))
|
||||||
sym->constValue = dynamic_cast<ConstExpr *>(init);
|
sym->constValue = dynamic_cast<ConstExpr *>(init);
|
||||||
}
|
}
|
||||||
@@ -329,7 +329,7 @@ DeclStmt::Print(int indent) const {
|
|||||||
printf("%*cDecl Stmt:", indent, ' ');
|
printf("%*cDecl Stmt:", indent, ' ');
|
||||||
pos.Print();
|
pos.Print();
|
||||||
for (unsigned int i = 0; i < vars.size(); ++i) {
|
for (unsigned int i = 0; i < vars.size(); ++i) {
|
||||||
printf("%*cVariable %s (%s)", indent+4, ' ',
|
printf("%*cVariable %s (%s)", indent+4, ' ',
|
||||||
vars[i].sym->name.c_str(),
|
vars[i].sym->name.c_str(),
|
||||||
vars[i].sym->type->GetString().c_str());
|
vars[i].sym->type->GetString().c_str());
|
||||||
if (vars[i].init != NULL) {
|
if (vars[i].init != NULL) {
|
||||||
@@ -351,8 +351,8 @@ DeclStmt::EstimateCost() const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// IfStmt
|
// IfStmt
|
||||||
|
|
||||||
IfStmt::IfStmt(Expr *t, Stmt *ts, Stmt *fs, bool checkCoherence, SourcePos p)
|
IfStmt::IfStmt(Expr *t, Stmt *ts, Stmt *fs, bool checkCoherence, SourcePos p)
|
||||||
: Stmt(p), test(t), trueStmts(ts), falseStmts(fs),
|
: Stmt(p), test(t), trueStmts(ts), falseStmts(fs),
|
||||||
doAllCheck(checkCoherence &&
|
doAllCheck(checkCoherence &&
|
||||||
!g->opt.disableCoherentControlFlow) {
|
!g->opt.disableCoherentControlFlow) {
|
||||||
}
|
}
|
||||||
@@ -399,9 +399,9 @@ IfStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// First check all of the things that might happen due to errors
|
// First check all of the things that might happen due to errors
|
||||||
// earlier in compilation and bail out if needed so that we don't
|
// earlier in compilation and bail out if needed so that we don't
|
||||||
// dereference NULL pointers in the below...
|
// dereference NULL pointers in the below...
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
if (!test)
|
if (!test)
|
||||||
return;
|
return;
|
||||||
const Type *testType = test->GetType();
|
const Type *testType = test->GetType();
|
||||||
if (!testType)
|
if (!testType)
|
||||||
@@ -433,7 +433,7 @@ IfStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// Emit code for the 'true' case
|
// Emit code for the 'true' case
|
||||||
ctx->SetCurrentBasicBlock(bthen);
|
ctx->SetCurrentBasicBlock(bthen);
|
||||||
lEmitIfStatements(ctx, trueStmts, "true");
|
lEmitIfStatements(ctx, trueStmts, "true");
|
||||||
if (ctx->GetCurrentBasicBlock())
|
if (ctx->GetCurrentBasicBlock())
|
||||||
ctx->BranchInst(bexit);
|
ctx->BranchInst(bexit);
|
||||||
|
|
||||||
// Emit code for the 'false' case
|
// Emit code for the 'false' case
|
||||||
@@ -466,10 +466,10 @@ IfStmt::TypeCheck() {
|
|||||||
if (test != NULL) {
|
if (test != NULL) {
|
||||||
const Type *testType = test->GetType();
|
const Type *testType = test->GetType();
|
||||||
if (testType != NULL) {
|
if (testType != NULL) {
|
||||||
bool isUniform = (testType->IsUniformType() &&
|
bool isUniform = (testType->IsUniformType() &&
|
||||||
!g->opt.disableUniformControlFlow);
|
!g->opt.disableUniformControlFlow);
|
||||||
test = TypeConvertExpr(test, isUniform ? AtomicType::UniformBool :
|
test = TypeConvertExpr(test, isUniform ? AtomicType::UniformBool :
|
||||||
AtomicType::VaryingBool,
|
AtomicType::VaryingBool,
|
||||||
"\"if\" statement test");
|
"\"if\" statement test");
|
||||||
if (test == NULL)
|
if (test == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -509,17 +509,17 @@ IfStmt::Print(int indent) const {
|
|||||||
|
|
||||||
|
|
||||||
/** Emit code to run both the true and false statements for the if test,
|
/** Emit code to run both the true and false statements for the if test,
|
||||||
with the mask set appropriately before running each one.
|
with the mask set appropriately before running each one.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
IfStmt::emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
IfStmt::emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||||
llvm::Value *test) const {
|
llvm::Value *test) const {
|
||||||
if (trueStmts) {
|
if (trueStmts) {
|
||||||
ctx->SetInternalMaskAnd(oldMask, test);
|
ctx->SetInternalMaskAnd(oldMask, test);
|
||||||
lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements");
|
lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements");
|
||||||
// under varying control flow,, returns can't stop instruction
|
// under varying control flow,, returns can't stop instruction
|
||||||
// emission, so this better be non-NULL...
|
// emission, so this better be non-NULL...
|
||||||
AssertPos(ctx->GetDebugPos(), ctx->GetCurrentBasicBlock());
|
AssertPos(ctx->GetDebugPos(), ctx->GetCurrentBasicBlock());
|
||||||
}
|
}
|
||||||
if (falseStmts) {
|
if (falseStmts) {
|
||||||
ctx->SetInternalMaskAndNot(oldMask, test);
|
ctx->SetInternalMaskAndNot(oldMask, test);
|
||||||
@@ -544,14 +544,14 @@ IfStmt::emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *ltest) const {
|
|||||||
llvm::BasicBlock *bMixedOn = ctx->CreateBasicBlock("cif_mask_mixed");
|
llvm::BasicBlock *bMixedOn = ctx->CreateBasicBlock("cif_mask_mixed");
|
||||||
llvm::BasicBlock *bDone = ctx->CreateBasicBlock("cif_done");
|
llvm::BasicBlock *bDone = ctx->CreateBasicBlock("cif_done");
|
||||||
|
|
||||||
// Jump to either bAllOn or bMixedOn, depending on the mask's value
|
// Jump to either bAllOn or bMixedOn, depending on the mask's value
|
||||||
llvm::Value *maskAllQ = ctx->All(ctx->GetFullMask());
|
llvm::Value *maskAllQ = ctx->All(ctx->GetFullMask());
|
||||||
ctx->BranchInst(bAllOn, bMixedOn, maskAllQ);
|
ctx->BranchInst(bAllOn, bMixedOn, maskAllQ);
|
||||||
|
|
||||||
// Emit code for the 'mask all on' case
|
// Emit code for the 'mask all on' case
|
||||||
ctx->SetCurrentBasicBlock(bAllOn);
|
ctx->SetCurrentBasicBlock(bAllOn);
|
||||||
emitMaskAllOn(ctx, ltest, bDone);
|
emitMaskAllOn(ctx, ltest, bDone);
|
||||||
|
|
||||||
// And emit code for the mixed mask case
|
// And emit code for the mixed mask case
|
||||||
ctx->SetCurrentBasicBlock(bMixedOn);
|
ctx->SetCurrentBasicBlock(bMixedOn);
|
||||||
emitMaskMixed(ctx, oldMask, ltest, bDone);
|
emitMaskMixed(ctx, oldMask, ltest, bDone);
|
||||||
@@ -580,7 +580,7 @@ IfStmt::emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *ltest) const {
|
|||||||
//
|
//
|
||||||
// where our use of blend for conditional assignments doesn't check
|
// where our use of blend for conditional assignments doesn't check
|
||||||
// for the 'all lanes' off case.
|
// for the 'all lanes' off case.
|
||||||
int trueFalseCost = (::EstimateCost(trueStmts) +
|
int trueFalseCost = (::EstimateCost(trueStmts) +
|
||||||
::EstimateCost(falseStmts));
|
::EstimateCost(falseStmts));
|
||||||
bool costIsAcceptable = (trueFalseCost <
|
bool costIsAcceptable = (trueFalseCost <
|
||||||
PREDICATE_SAFE_IF_STATEMENT_COST);
|
PREDICATE_SAFE_IF_STATEMENT_COST);
|
||||||
@@ -591,7 +591,7 @@ IfStmt::emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *ltest) const {
|
|||||||
Debug(pos, "If statement: true cost %d (safe %d), false cost %d (safe %d).",
|
Debug(pos, "If statement: true cost %d (safe %d), false cost %d (safe %d).",
|
||||||
::EstimateCost(trueStmts), (int)SafeToRunWithMaskAllOff(trueStmts),
|
::EstimateCost(trueStmts), (int)SafeToRunWithMaskAllOff(trueStmts),
|
||||||
::EstimateCost(falseStmts), (int)SafeToRunWithMaskAllOff(falseStmts));
|
::EstimateCost(falseStmts), (int)SafeToRunWithMaskAllOff(falseStmts));
|
||||||
|
|
||||||
if (safeToRunWithAllLanesOff &&
|
if (safeToRunWithAllLanesOff &&
|
||||||
(costIsAcceptable || g->opt.disableCoherentControlFlow)) {
|
(costIsAcceptable || g->opt.disableCoherentControlFlow)) {
|
||||||
ctx->StartVaryingIf(oldMask);
|
ctx->StartVaryingIf(oldMask);
|
||||||
@@ -612,7 +612,7 @@ IfStmt::emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *ltest) const {
|
|||||||
mask is all on going into the 'if'.
|
mask is all on going into the 'if'.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
IfStmt::emitMaskAllOn(FunctionEmitContext *ctx, llvm::Value *ltest,
|
IfStmt::emitMaskAllOn(FunctionEmitContext *ctx, llvm::Value *ltest,
|
||||||
llvm::BasicBlock *bDone) const {
|
llvm::BasicBlock *bDone) const {
|
||||||
// We start by explicitly storing "all on" into the mask mask. Note
|
// We start by explicitly storing "all on" into the mask mask. Note
|
||||||
// that this doesn't change its actual value, but doing so lets the
|
// that this doesn't change its actual value, but doing so lets the
|
||||||
@@ -682,7 +682,7 @@ IfStmt::emitMaskAllOn(FunctionEmitContext *ctx, llvm::Value *ltest,
|
|||||||
on/off going into it.
|
on/off going into it.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
IfStmt::emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
IfStmt::emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||||
llvm::Value *ltest, llvm::BasicBlock *bDone) const {
|
llvm::Value *ltest, llvm::BasicBlock *bDone) const {
|
||||||
ctx->StartVaryingIf(oldMask);
|
ctx->StartVaryingIf(oldMask);
|
||||||
llvm::BasicBlock *bNext = ctx->CreateBasicBlock("safe_if_after_true");
|
llvm::BasicBlock *bNext = ctx->CreateBasicBlock("safe_if_after_true");
|
||||||
@@ -699,7 +699,7 @@ IfStmt::emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
|||||||
ctx->SetCurrentBasicBlock(bRunTrue);
|
ctx->SetCurrentBasicBlock(bRunTrue);
|
||||||
if (trueStmts != NULL)
|
if (trueStmts != NULL)
|
||||||
lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements");
|
lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements");
|
||||||
AssertPos(pos, ctx->GetCurrentBasicBlock());
|
AssertPos(pos, ctx->GetCurrentBasicBlock());
|
||||||
ctx->BranchInst(bNext);
|
ctx->BranchInst(bNext);
|
||||||
ctx->SetCurrentBasicBlock(bNext);
|
ctx->SetCurrentBasicBlock(bNext);
|
||||||
|
|
||||||
@@ -801,7 +801,7 @@ lVaryingBCPostFunc(ASTNode *node, void *d) {
|
|||||||
flow. We need to detect this case for loops since what might otherwise
|
flow. We need to detect this case for loops since what might otherwise
|
||||||
look like a 'uniform' loop needs to have code emitted to do all of the
|
look like a 'uniform' loop needs to have code emitted to do all of the
|
||||||
lane management stuff if this is the case.
|
lane management stuff if this is the case.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
lHasVaryingBreakOrContinue(Stmt *stmt) {
|
lHasVaryingBreakOrContinue(Stmt *stmt) {
|
||||||
VaryingBCCheckInfo info;
|
VaryingBCCheckInfo info;
|
||||||
@@ -810,8 +810,8 @@ lHasVaryingBreakOrContinue(Stmt *stmt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DoStmt::DoStmt(Expr *t, Stmt *s, bool cc, SourcePos p)
|
DoStmt::DoStmt(Expr *t, Stmt *s, bool cc, SourcePos p)
|
||||||
: Stmt(p), testExpr(t), bodyStmts(s),
|
: Stmt(p), testExpr(t), bodyStmts(s),
|
||||||
doCoherentCheck(cc && !g->opt.disableCoherentControlFlow) {
|
doCoherentCheck(cc && !g->opt.disableCoherentControlFlow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -819,9 +819,9 @@ DoStmt::DoStmt(Expr *t, Stmt *s, bool cc, SourcePos p)
|
|||||||
void DoStmt::EmitCode(FunctionEmitContext *ctx) const {
|
void DoStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
// Check for things that could be NULL due to earlier errors during
|
// Check for things that could be NULL due to earlier errors during
|
||||||
// compilation.
|
// compilation.
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
if (!testExpr || !testExpr->GetType())
|
if (!testExpr || !testExpr->GetType())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool uniformTest = testExpr->GetType()->IsUniformType();
|
bool uniformTest = testExpr->GetType()->IsUniformType();
|
||||||
@@ -984,15 +984,15 @@ DoStmt::Print(int indent) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// ForStmt
|
// ForStmt
|
||||||
|
|
||||||
ForStmt::ForStmt(Stmt *i, Expr *t, Stmt *s, Stmt *st, bool cc, SourcePos p)
|
ForStmt::ForStmt(Stmt *i, Expr *t, Stmt *s, Stmt *st, bool cc, SourcePos p)
|
||||||
: Stmt(p), init(i), test(t), step(s), stmts(st),
|
: Stmt(p), init(i), test(t), step(s), stmts(st),
|
||||||
doCoherentCheck(cc && !g->opt.disableCoherentControlFlow) {
|
doCoherentCheck(cc && !g->opt.disableCoherentControlFlow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ForStmt::EmitCode(FunctionEmitContext *ctx) const {
|
ForStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
llvm::BasicBlock *btest = ctx->CreateBasicBlock("for_test");
|
llvm::BasicBlock *btest = ctx->CreateBasicBlock("for_test");
|
||||||
@@ -1176,14 +1176,14 @@ ForStmt::Print(int indent) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// BreakStmt
|
// BreakStmt
|
||||||
|
|
||||||
BreakStmt::BreakStmt(SourcePos p)
|
BreakStmt::BreakStmt(SourcePos p)
|
||||||
: Stmt(p) {
|
: Stmt(p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BreakStmt::EmitCode(FunctionEmitContext *ctx) const {
|
BreakStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctx->SetDebugPos(pos);
|
ctx->SetDebugPos(pos);
|
||||||
@@ -1214,14 +1214,14 @@ BreakStmt::Print(int indent) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// ContinueStmt
|
// ContinueStmt
|
||||||
|
|
||||||
ContinueStmt::ContinueStmt(SourcePos p)
|
ContinueStmt::ContinueStmt(SourcePos p)
|
||||||
: Stmt(p) {
|
: Stmt(p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ContinueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
ContinueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctx->SetDebugPos(pos);
|
ctx->SetDebugPos(pos);
|
||||||
@@ -1252,9 +1252,9 @@ ContinueStmt::Print(int indent) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// ForeachStmt
|
// ForeachStmt
|
||||||
|
|
||||||
ForeachStmt::ForeachStmt(const std::vector<Symbol *> &lvs,
|
ForeachStmt::ForeachStmt(const std::vector<Symbol *> &lvs,
|
||||||
const std::vector<Expr *> &se,
|
const std::vector<Expr *> &se,
|
||||||
const std::vector<Expr *> &ee,
|
const std::vector<Expr *> &ee,
|
||||||
Stmt *s, bool t, SourcePos pos)
|
Stmt *s, bool t, SourcePos pos)
|
||||||
: Stmt(pos), dimVariables(lvs), startExprs(se), endExprs(ee), isTiled(t),
|
: Stmt(pos), dimVariables(lvs), startExprs(se), endExprs(ee), isTiled(t),
|
||||||
stmts(s) {
|
stmts(s) {
|
||||||
@@ -1266,16 +1266,16 @@ ForeachStmt::ForeachStmt(const std::vector<Symbol *> &lvs,
|
|||||||
values for use within the loop body.
|
values for use within the loop body.
|
||||||
*/
|
*/
|
||||||
static llvm::Value *
|
static llvm::Value *
|
||||||
lUpdateVaryingCounter(int dim, int nDims, FunctionEmitContext *ctx,
|
lUpdateVaryingCounter(int dim, int nDims, FunctionEmitContext *ctx,
|
||||||
llvm::Value *uniformCounterPtr,
|
llvm::Value *uniformCounterPtr,
|
||||||
llvm::Value *varyingCounterPtr,
|
llvm::Value *varyingCounterPtr,
|
||||||
const std::vector<int> &spans) {
|
const std::vector<int> &spans) {
|
||||||
// Smear the uniform counter value out to be varying
|
// Smear the uniform counter value out to be varying
|
||||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtr);
|
llvm::Value *counter = ctx->LoadInst(uniformCounterPtr);
|
||||||
llvm::Value *smearCounter =
|
llvm::Value *smearCounter =
|
||||||
llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
||||||
for (int i = 0; i < g->target.vectorWidth; ++i)
|
for (int i = 0; i < g->target.vectorWidth; ++i)
|
||||||
smearCounter =
|
smearCounter =
|
||||||
ctx->InsertInst(smearCounter, counter, i, "smear_counter");
|
ctx->InsertInst(smearCounter, counter, i, "smear_counter");
|
||||||
|
|
||||||
// Figure out the offsets; this is a little bit tricky. As an example,
|
// Figure out the offsets; this is a little bit tricky. As an example,
|
||||||
@@ -1300,7 +1300,7 @@ lUpdateVaryingCounter(int dim, int nDims, FunctionEmitContext *ctx,
|
|||||||
|
|
||||||
// Add the deltas to compute the varying counter values; store the
|
// Add the deltas to compute the varying counter values; store the
|
||||||
// result to memory and then return it directly as well.
|
// result to memory and then return it directly as well.
|
||||||
llvm::Value *varyingCounter =
|
llvm::Value *varyingCounter =
|
||||||
ctx->BinaryOperator(llvm::Instruction::Add, smearCounter,
|
ctx->BinaryOperator(llvm::Instruction::Add, smearCounter,
|
||||||
LLVMInt32Vector(delta), "iter_val");
|
LLVMInt32Vector(delta), "iter_val");
|
||||||
ctx->StoreInst(varyingCounter, varyingCounterPtr);
|
ctx->StoreInst(varyingCounter, varyingCounterPtr);
|
||||||
@@ -1349,7 +1349,7 @@ lGetSpans(int dimsLeft, int nDims, int itemsLeft, bool isTiled, int *a) {
|
|||||||
// 16-wide.
|
// 16-wide.
|
||||||
*a = 4;
|
*a = 4;
|
||||||
else
|
else
|
||||||
// Otherwise give this dimension a span of two.
|
// Otherwise give this dimension a span of two.
|
||||||
*a = 2;
|
*a = 2;
|
||||||
|
|
||||||
lGetSpans(dimsLeft-1, nDims, itemsLeft / *a, isTiled, a+1);
|
lGetSpans(dimsLeft-1, nDims, itemsLeft / *a, isTiled, a+1);
|
||||||
@@ -1364,7 +1364,7 @@ lGetSpans(int dimsLeft, int nDims, int itemsLeft, bool isTiled, int *a) {
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (ctx->GetCurrentBasicBlock() == NULL || stmts == NULL)
|
if (ctx->GetCurrentBasicBlock() == NULL || stmts == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
llvm::BasicBlock *bbFullBody = ctx->CreateBasicBlock("foreach_full_body");
|
llvm::BasicBlock *bbFullBody = ctx->CreateBasicBlock("foreach_full_body");
|
||||||
@@ -1381,7 +1381,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
ctx->SetFunctionMask(LLVMMaskAllOn);
|
ctx->SetFunctionMask(LLVMMaskAllOn);
|
||||||
|
|
||||||
// This should be caught during typechecking
|
// This should be caught during typechecking
|
||||||
AssertPos(pos, startExprs.size() == dimVariables.size() &&
|
AssertPos(pos, startExprs.size() == dimVariables.size() &&
|
||||||
endExprs.size() == dimVariables.size());
|
endExprs.size() == dimVariables.size());
|
||||||
int nDims = (int)dimVariables.size();
|
int nDims = (int)dimVariables.size();
|
||||||
|
|
||||||
@@ -1413,7 +1413,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
endVals.push_back(ev);
|
endVals.push_back(ev);
|
||||||
|
|
||||||
// nItems = endVal - startVal
|
// nItems = endVal - startVal
|
||||||
llvm::Value *nItems =
|
llvm::Value *nItems =
|
||||||
ctx->BinaryOperator(llvm::Instruction::Sub, ev, sv, "nitems");
|
ctx->BinaryOperator(llvm::Instruction::Sub, ev, sv, "nitems");
|
||||||
|
|
||||||
// nExtras = nItems % (span for this dimension)
|
// nExtras = nItems % (span for this dimension)
|
||||||
@@ -1432,15 +1432,15 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// goes from startVal to endVal, in steps of the span for this
|
// goes from startVal to endVal, in steps of the span for this
|
||||||
// dimension. Its value is only used internally here for looping
|
// dimension. Its value is only used internally here for looping
|
||||||
// logic and isn't directly available in the user's program code.
|
// logic and isn't directly available in the user's program code.
|
||||||
uniformCounterPtrs.push_back(ctx->AllocaInst(LLVMTypes::Int32Type,
|
uniformCounterPtrs.push_back(ctx->AllocaInst(LLVMTypes::Int32Type,
|
||||||
"counter"));
|
"counter"));
|
||||||
ctx->StoreInst(startVals[i], uniformCounterPtrs[i]);
|
ctx->StoreInst(startVals[i], uniformCounterPtrs[i]);
|
||||||
|
|
||||||
// There is also a varying variable that holds the set of index
|
// There is also a varying variable that holds the set of index
|
||||||
// values for each dimension in the current loop iteration; this is
|
// values for each dimension in the current loop iteration; this is
|
||||||
// the value that is program-visible.
|
// the value that is program-visible.
|
||||||
dimVariables[i]->storagePtr =
|
dimVariables[i]->storagePtr =
|
||||||
ctx->AllocaInst(LLVMTypes::Int32VectorType,
|
ctx->AllocaInst(LLVMTypes::Int32VectorType,
|
||||||
dimVariables[i]->name.c_str());
|
dimVariables[i]->name.c_str());
|
||||||
dimVariables[i]->parentFunction = ctx->GetFunction();
|
dimVariables[i]->parentFunction = ctx->GetFunction();
|
||||||
ctx->EmitVariableDebugInfo(dimVariables[i]);
|
ctx->EmitVariableDebugInfo(dimVariables[i]);
|
||||||
@@ -1482,7 +1482,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
for (int i = 0; i < nDims-1; ++i) {
|
for (int i = 0; i < nDims-1; ++i) {
|
||||||
ctx->SetCurrentBasicBlock(bbStep[i]);
|
ctx->SetCurrentBasicBlock(bbStep[i]);
|
||||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[i]);
|
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[i]);
|
||||||
llvm::Value *newCounter =
|
llvm::Value *newCounter =
|
||||||
ctx->BinaryOperator(llvm::Instruction::Add, counter,
|
ctx->BinaryOperator(llvm::Instruction::Add, counter,
|
||||||
LLVMInt32(span[i]), "new_counter");
|
LLVMInt32(span[i]), "new_counter");
|
||||||
ctx->StoreInst(newCounter, uniformCounterPtrs[i]);
|
ctx->StoreInst(newCounter, uniformCounterPtrs[i]);
|
||||||
@@ -1495,15 +1495,15 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
for (int i = 0; i < nDims-1; ++i) {
|
for (int i = 0; i < nDims-1; ++i) {
|
||||||
ctx->SetCurrentBasicBlock(bbTest[i]);
|
ctx->SetCurrentBasicBlock(bbTest[i]);
|
||||||
|
|
||||||
llvm::Value *haveExtras =
|
llvm::Value *haveExtras =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGT,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGT,
|
||||||
endVals[i], alignedEnd[i], "have_extras");
|
endVals[i], alignedEnd[i], "have_extras");
|
||||||
|
|
||||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[i], "counter");
|
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[i], "counter");
|
||||||
llvm::Value *atAlignedEnd =
|
llvm::Value *atAlignedEnd =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
|
||||||
counter, alignedEnd[i], "at_aligned_end");
|
counter, alignedEnd[i], "at_aligned_end");
|
||||||
llvm::Value *inEx =
|
llvm::Value *inEx =
|
||||||
ctx->BinaryOperator(llvm::Instruction::And, haveExtras,
|
ctx->BinaryOperator(llvm::Instruction::And, haveExtras,
|
||||||
atAlignedEnd, "in_extras");
|
atAlignedEnd, "in_extras");
|
||||||
|
|
||||||
@@ -1513,8 +1513,8 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
inExtras.push_back(ctx->BinaryOperator(llvm::Instruction::Or, inEx,
|
inExtras.push_back(ctx->BinaryOperator(llvm::Instruction::Or, inEx,
|
||||||
inExtras[i-1], "in_extras_all"));
|
inExtras[i-1], "in_extras_all"));
|
||||||
|
|
||||||
llvm::Value *varyingCounter =
|
llvm::Value *varyingCounter =
|
||||||
lUpdateVaryingCounter(i, nDims, ctx, uniformCounterPtrs[i],
|
lUpdateVaryingCounter(i, nDims, ctx, uniformCounterPtrs[i],
|
||||||
dimVariables[i]->storagePtr, span);
|
dimVariables[i]->storagePtr, span);
|
||||||
|
|
||||||
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
||||||
@@ -1522,7 +1522,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
smearEnd = ctx->InsertInst(smearEnd, endVals[i], j, "smear_end");
|
smearEnd = ctx->InsertInst(smearEnd, endVals[i], j, "smear_end");
|
||||||
// Do a vector compare of its value to the end value to generate a
|
// Do a vector compare of its value to the end value to generate a
|
||||||
// mask for this last bit of work.
|
// mask for this last bit of work.
|
||||||
llvm::Value *emask =
|
llvm::Value *emask =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||||
varyingCounter, smearEnd);
|
varyingCounter, smearEnd);
|
||||||
emask = ctx->I1VecToBoolVec(emask);
|
emask = ctx->I1VecToBoolVec(emask);
|
||||||
@@ -1537,7 +1537,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
ctx->StoreInst(newMask, extrasMaskPtrs[i]);
|
ctx->StoreInst(newMask, extrasMaskPtrs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value *notAtEnd =
|
llvm::Value *notAtEnd =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||||
counter, endVals[i]);
|
counter, endVals[i]);
|
||||||
ctx->BranchInst(bbTest[i+1], bbReset[i], notAtEnd);
|
ctx->BranchInst(bbTest[i+1], bbReset[i], notAtEnd);
|
||||||
@@ -1576,9 +1576,9 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// whether any of the enclosing dimensions is partially active
|
// whether any of the enclosing dimensions is partially active
|
||||||
// (i.e. processing extra elements that don't exactly fit into a
|
// (i.e. processing extra elements that don't exactly fit into a
|
||||||
// vector).
|
// vector).
|
||||||
llvm::BasicBlock *bbOuterInExtras =
|
llvm::BasicBlock *bbOuterInExtras =
|
||||||
ctx->CreateBasicBlock("outer_in_extras");
|
ctx->CreateBasicBlock("outer_in_extras");
|
||||||
llvm::BasicBlock *bbOuterNotInExtras =
|
llvm::BasicBlock *bbOuterNotInExtras =
|
||||||
ctx->CreateBasicBlock("outer_not_in_extras");
|
ctx->CreateBasicBlock("outer_not_in_extras");
|
||||||
|
|
||||||
ctx->SetCurrentBasicBlock(bbTest[nDims-1]);
|
ctx->SetCurrentBasicBlock(bbTest[nDims-1]);
|
||||||
@@ -1609,12 +1609,12 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
ctx->SetCurrentBasicBlock(bbOuterInExtras); {
|
ctx->SetCurrentBasicBlock(bbOuterInExtras); {
|
||||||
// Update the varying counter value here, since all subsequent
|
// Update the varying counter value here, since all subsequent
|
||||||
// blocks along this path need it.
|
// blocks along this path need it.
|
||||||
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
|
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
|
||||||
dimVariables[nDims-1]->storagePtr, span);
|
dimVariables[nDims-1]->storagePtr, span);
|
||||||
|
|
||||||
// here we just check to see if counter < alignedEnd
|
// here we just check to see if counter < alignedEnd
|
||||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
|
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
|
||||||
llvm::Value *beforeAlignedEnd =
|
llvm::Value *beforeAlignedEnd =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||||
counter, alignedEnd[nDims-1], "before_aligned_end");
|
counter, alignedEnd[nDims-1], "before_aligned_end");
|
||||||
ctx->BranchInst(bbAllInnerPartialOuter, bbPartial, beforeAlignedEnd);
|
ctx->BranchInst(bbAllInnerPartialOuter, bbPartial, beforeAlignedEnd);
|
||||||
@@ -1624,7 +1624,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// case where the mask is partially but not fully on. This same block
|
// case where the mask is partially but not fully on. This same block
|
||||||
// runs in multiple cases: both for handling any ragged extra data for
|
// runs in multiple cases: both for handling any ragged extra data for
|
||||||
// the innermost dimension but also when outer dimensions have set the
|
// the innermost dimension but also when outer dimensions have set the
|
||||||
// mask to be partially on.
|
// mask to be partially on.
|
||||||
//
|
//
|
||||||
// The value stored in stepIndexAfterMaskedBodyPtr is used after each
|
// The value stored in stepIndexAfterMaskedBodyPtr is used after each
|
||||||
// execution of the body code to determine whether the innermost index
|
// execution of the body code to determine whether the innermost index
|
||||||
@@ -1660,12 +1660,12 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// We need to include the effect of the innermost dimension in the mask
|
// We need to include the effect of the innermost dimension in the mask
|
||||||
// for the final bits here
|
// for the final bits here
|
||||||
ctx->SetCurrentBasicBlock(bbPartial); {
|
ctx->SetCurrentBasicBlock(bbPartial); {
|
||||||
llvm::Value *varyingCounter =
|
llvm::Value *varyingCounter =
|
||||||
ctx->LoadInst(dimVariables[nDims-1]->storagePtr);
|
ctx->LoadInst(dimVariables[nDims-1]->storagePtr);
|
||||||
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
||||||
for (int j = 0; j < g->target.vectorWidth; ++j)
|
for (int j = 0; j < g->target.vectorWidth; ++j)
|
||||||
smearEnd = ctx->InsertInst(smearEnd, endVals[nDims-1], j, "smear_end");
|
smearEnd = ctx->InsertInst(smearEnd, endVals[nDims-1], j, "smear_end");
|
||||||
llvm::Value *emask =
|
llvm::Value *emask =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||||
varyingCounter, smearEnd);
|
varyingCounter, smearEnd);
|
||||||
emask = ctx->I1VecToBoolVec(emask);
|
emask = ctx->I1VecToBoolVec(emask);
|
||||||
@@ -1701,7 +1701,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
ctx->CreateBasicBlock("partial_inner_all_outer");
|
ctx->CreateBasicBlock("partial_inner_all_outer");
|
||||||
ctx->SetCurrentBasicBlock(bbOuterNotInExtras); {
|
ctx->SetCurrentBasicBlock(bbOuterNotInExtras); {
|
||||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
|
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
|
||||||
llvm::Value *beforeAlignedEnd =
|
llvm::Value *beforeAlignedEnd =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||||
counter, alignedEnd[nDims-1], "before_aligned_end");
|
counter, alignedEnd[nDims-1], "before_aligned_end");
|
||||||
ctx->BranchInst(bbFullBody, bbPartialInnerAllOuter,
|
ctx->BranchInst(bbFullBody, bbPartialInnerAllOuter,
|
||||||
@@ -1714,12 +1714,12 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// on'. This ends up being relatively straightforward: just update the
|
// on'. This ends up being relatively straightforward: just update the
|
||||||
// value of the varying loop counter and have the statements in the
|
// value of the varying loop counter and have the statements in the
|
||||||
// loop body emit their code.
|
// loop body emit their code.
|
||||||
llvm::BasicBlock *bbFullBodyContinue =
|
llvm::BasicBlock *bbFullBodyContinue =
|
||||||
ctx->CreateBasicBlock("foreach_full_continue");
|
ctx->CreateBasicBlock("foreach_full_continue");
|
||||||
ctx->SetCurrentBasicBlock(bbFullBody); {
|
ctx->SetCurrentBasicBlock(bbFullBody); {
|
||||||
ctx->SetInternalMask(LLVMMaskAllOn);
|
ctx->SetInternalMask(LLVMMaskAllOn);
|
||||||
ctx->SetBlockEntryMask(LLVMMaskAllOn);
|
ctx->SetBlockEntryMask(LLVMMaskAllOn);
|
||||||
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
|
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
|
||||||
dimVariables[nDims-1]->storagePtr, span);
|
dimVariables[nDims-1]->storagePtr, span);
|
||||||
ctx->SetContinueTarget(bbFullBodyContinue);
|
ctx->SetContinueTarget(bbFullBodyContinue);
|
||||||
ctx->AddInstrumentationPoint("foreach loop body (all on)");
|
ctx->AddInstrumentationPoint("foreach loop body (all on)");
|
||||||
@@ -1730,7 +1730,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
ctx->SetCurrentBasicBlock(bbFullBodyContinue); {
|
ctx->SetCurrentBasicBlock(bbFullBodyContinue); {
|
||||||
ctx->RestoreContinuedLanes();
|
ctx->RestoreContinuedLanes();
|
||||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1]);
|
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1]);
|
||||||
llvm::Value *newCounter =
|
llvm::Value *newCounter =
|
||||||
ctx->BinaryOperator(llvm::Instruction::Add, counter,
|
ctx->BinaryOperator(llvm::Instruction::Add, counter,
|
||||||
LLVMInt32(span[nDims-1]), "new_counter");
|
LLVMInt32(span[nDims-1]), "new_counter");
|
||||||
ctx->StoreInst(newCounter, uniformCounterPtrs[nDims-1]);
|
ctx->StoreInst(newCounter, uniformCounterPtrs[nDims-1]);
|
||||||
@@ -1741,11 +1741,11 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// We're done running blocks with the mask all on; see if the counter is
|
// We're done running blocks with the mask all on; see if the counter is
|
||||||
// less than the end value, in which case we need to run the body one
|
// less than the end value, in which case we need to run the body one
|
||||||
// more time to get the extra bits.
|
// more time to get the extra bits.
|
||||||
llvm::BasicBlock *bbSetInnerMask =
|
llvm::BasicBlock *bbSetInnerMask =
|
||||||
ctx->CreateBasicBlock("partial_inner_only");
|
ctx->CreateBasicBlock("partial_inner_only");
|
||||||
ctx->SetCurrentBasicBlock(bbPartialInnerAllOuter); {
|
ctx->SetCurrentBasicBlock(bbPartialInnerAllOuter); {
|
||||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
|
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1], "counter");
|
||||||
llvm::Value *beforeFullEnd =
|
llvm::Value *beforeFullEnd =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||||
counter, endVals[nDims-1], "before_full_end");
|
counter, endVals[nDims-1], "before_full_end");
|
||||||
ctx->BranchInst(bbSetInnerMask, bbReset[nDims-1], beforeFullEnd);
|
ctx->BranchInst(bbSetInnerMask, bbReset[nDims-1], beforeFullEnd);
|
||||||
@@ -1755,13 +1755,13 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// The outer dimensions are all on, so the mask is just given by the
|
// The outer dimensions are all on, so the mask is just given by the
|
||||||
// mask for the innermost dimension
|
// mask for the innermost dimension
|
||||||
ctx->SetCurrentBasicBlock(bbSetInnerMask); {
|
ctx->SetCurrentBasicBlock(bbSetInnerMask); {
|
||||||
llvm::Value *varyingCounter =
|
llvm::Value *varyingCounter =
|
||||||
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
|
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
|
||||||
dimVariables[nDims-1]->storagePtr, span);
|
dimVariables[nDims-1]->storagePtr, span);
|
||||||
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
llvm::Value *smearEnd = llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
||||||
for (int j = 0; j < g->target.vectorWidth; ++j)
|
for (int j = 0; j < g->target.vectorWidth; ++j)
|
||||||
smearEnd = ctx->InsertInst(smearEnd, endVals[nDims-1], j, "smear_end");
|
smearEnd = ctx->InsertInst(smearEnd, endVals[nDims-1], j, "smear_end");
|
||||||
llvm::Value *emask =
|
llvm::Value *emask =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT,
|
||||||
varyingCounter, smearEnd);
|
varyingCounter, smearEnd);
|
||||||
emask = ctx->I1VecToBoolVec(emask);
|
emask = ctx->I1VecToBoolVec(emask);
|
||||||
@@ -1778,9 +1778,9 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// of the statements' code, since the code above is emitted with the
|
// of the statements' code, since the code above is emitted with the
|
||||||
// mask known to be all-on, which in turn leads to more efficient code
|
// mask known to be all-on, which in turn leads to more efficient code
|
||||||
// for that case.
|
// for that case.
|
||||||
llvm::BasicBlock *bbStepInnerIndex =
|
llvm::BasicBlock *bbStepInnerIndex =
|
||||||
ctx->CreateBasicBlock("step_inner_index");
|
ctx->CreateBasicBlock("step_inner_index");
|
||||||
llvm::BasicBlock *bbMaskedBodyContinue =
|
llvm::BasicBlock *bbMaskedBodyContinue =
|
||||||
ctx->CreateBasicBlock("foreach_masked_continue");
|
ctx->CreateBasicBlock("foreach_masked_continue");
|
||||||
ctx->SetCurrentBasicBlock(bbMaskedBody); {
|
ctx->SetCurrentBasicBlock(bbMaskedBody); {
|
||||||
ctx->AddInstrumentationPoint("foreach loop body (masked)");
|
ctx->AddInstrumentationPoint("foreach loop body (masked)");
|
||||||
@@ -1802,7 +1802,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// innermost for loop over full vectors.
|
// innermost for loop over full vectors.
|
||||||
ctx->SetCurrentBasicBlock(bbStepInnerIndex); {
|
ctx->SetCurrentBasicBlock(bbStepInnerIndex); {
|
||||||
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1]);
|
llvm::Value *counter = ctx->LoadInst(uniformCounterPtrs[nDims-1]);
|
||||||
llvm::Value *newCounter =
|
llvm::Value *newCounter =
|
||||||
ctx->BinaryOperator(llvm::Instruction::Add, counter,
|
ctx->BinaryOperator(llvm::Instruction::Add, counter,
|
||||||
LLVMInt32(span[nDims-1]), "new_counter");
|
LLVMInt32(span[nDims-1]), "new_counter");
|
||||||
ctx->StoreInst(newCounter, uniformCounterPtrs[nDims-1]);
|
ctx->StoreInst(newCounter, uniformCounterPtrs[nDims-1]);
|
||||||
@@ -1826,8 +1826,8 @@ ForeachStmt::TypeCheck() {
|
|||||||
bool anyErrors = false;
|
bool anyErrors = false;
|
||||||
for (unsigned int i = 0; i < startExprs.size(); ++i) {
|
for (unsigned int i = 0; i < startExprs.size(); ++i) {
|
||||||
if (startExprs[i] != NULL)
|
if (startExprs[i] != NULL)
|
||||||
startExprs[i] = TypeConvertExpr(startExprs[i],
|
startExprs[i] = TypeConvertExpr(startExprs[i],
|
||||||
AtomicType::UniformInt32,
|
AtomicType::UniformInt32,
|
||||||
"foreach starting value");
|
"foreach starting value");
|
||||||
anyErrors |= (startExprs[i] == NULL);
|
anyErrors |= (startExprs[i] == NULL);
|
||||||
}
|
}
|
||||||
@@ -1875,12 +1875,12 @@ ForeachStmt::Print(int indent) const {
|
|||||||
printf("%*cForeach Stmt", indent, ' ');
|
printf("%*cForeach Stmt", indent, ' ');
|
||||||
pos.Print();
|
pos.Print();
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
for (unsigned int i = 0; i < dimVariables.size(); ++i)
|
for (unsigned int i = 0; i < dimVariables.size(); ++i)
|
||||||
if (dimVariables[i] != NULL)
|
if (dimVariables[i] != NULL)
|
||||||
printf("%*cVar %d: %s\n", indent+4, ' ', i,
|
printf("%*cVar %d: %s\n", indent+4, ' ', i,
|
||||||
dimVariables[i]->name.c_str());
|
dimVariables[i]->name.c_str());
|
||||||
else
|
else
|
||||||
printf("%*cVar %d: NULL\n", indent+4, ' ', i);
|
printf("%*cVar %d: NULL\n", indent+4, ' ', i);
|
||||||
|
|
||||||
printf("Start values:\n");
|
printf("Start values:\n");
|
||||||
@@ -1917,7 +1917,7 @@ ForeachStmt::Print(int indent) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// ForeachActiveStmt
|
// ForeachActiveStmt
|
||||||
|
|
||||||
ForeachActiveStmt::ForeachActiveStmt(Symbol *s, Stmt *st, SourcePos pos)
|
ForeachActiveStmt::ForeachActiveStmt(Symbol *s, Stmt *st, SourcePos pos)
|
||||||
: Stmt(pos) {
|
: Stmt(pos) {
|
||||||
sym = s;
|
sym = s;
|
||||||
stmts = st;
|
stmts = st;
|
||||||
@@ -1926,7 +1926,7 @@ ForeachActiveStmt::ForeachActiveStmt(Symbol *s, Stmt *st, SourcePos pos)
|
|||||||
|
|
||||||
void
|
void
|
||||||
ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Allocate storage for the symbol that we'll use for the uniform
|
// Allocate storage for the symbol that we'll use for the uniform
|
||||||
@@ -1936,7 +1936,7 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Assert(Type::Equal(sym->type,
|
Assert(Type::Equal(sym->type,
|
||||||
AtomicType::UniformInt64->GetAsConstType()));
|
AtomicType::UniformInt64->GetAsConstType()));
|
||||||
sym->storagePtr = ctx->AllocaInst(LLVMTypes::Int64Type, sym->name.c_str());
|
sym->storagePtr = ctx->AllocaInst(LLVMTypes::Int64Type, sym->name.c_str());
|
||||||
|
|
||||||
@@ -1944,22 +1944,22 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
ctx->EmitVariableDebugInfo(sym);
|
ctx->EmitVariableDebugInfo(sym);
|
||||||
|
|
||||||
// The various basic blocks that we'll need in the below
|
// The various basic blocks that we'll need in the below
|
||||||
llvm::BasicBlock *bbFindNext =
|
llvm::BasicBlock *bbFindNext =
|
||||||
ctx->CreateBasicBlock("foreach_active_find_next");
|
ctx->CreateBasicBlock("foreach_active_find_next");
|
||||||
llvm::BasicBlock *bbBody = ctx->CreateBasicBlock("foreach_active_body");
|
llvm::BasicBlock *bbBody = ctx->CreateBasicBlock("foreach_active_body");
|
||||||
llvm::BasicBlock *bbCheckForMore =
|
llvm::BasicBlock *bbCheckForMore =
|
||||||
ctx->CreateBasicBlock("foreach_active_check_for_more");
|
ctx->CreateBasicBlock("foreach_active_check_for_more");
|
||||||
llvm::BasicBlock *bbDone = ctx->CreateBasicBlock("foreach_active_done");
|
llvm::BasicBlock *bbDone = ctx->CreateBasicBlock("foreach_active_done");
|
||||||
|
|
||||||
// Save the old mask so that we can restore it at the end
|
// Save the old mask so that we can restore it at the end
|
||||||
llvm::Value *oldInternalMask = ctx->GetInternalMask();
|
llvm::Value *oldInternalMask = ctx->GetInternalMask();
|
||||||
|
|
||||||
// Now, *maskBitsPtr will maintain a bitmask for the lanes that remain
|
// Now, *maskBitsPtr will maintain a bitmask for the lanes that remain
|
||||||
// to be processed by a pass through the loop body. It starts out with
|
// to be processed by a pass through the loop body. It starts out with
|
||||||
// the current execution mask (which should never be all off going in
|
// the current execution mask (which should never be all off going in
|
||||||
// to this)...
|
// to this)...
|
||||||
llvm::Value *oldFullMask = ctx->GetFullMask();
|
llvm::Value *oldFullMask = ctx->GetFullMask();
|
||||||
llvm::Value *maskBitsPtr =
|
llvm::Value *maskBitsPtr =
|
||||||
ctx->AllocaInst(LLVMTypes::Int64Type, "mask_bits");
|
ctx->AllocaInst(LLVMTypes::Int64Type, "mask_bits");
|
||||||
llvm::Value *movmsk = ctx->LaneMask(oldFullMask);
|
llvm::Value *movmsk = ctx->LaneMask(oldFullMask);
|
||||||
ctx->StoreInst(movmsk, maskBitsPtr);
|
ctx->StoreInst(movmsk, maskBitsPtr);
|
||||||
@@ -1971,13 +1971,13 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
|
|
||||||
// Onward to find the first set of program instance to run the loop for
|
// Onward to find the first set of program instance to run the loop for
|
||||||
ctx->BranchInst(bbFindNext);
|
ctx->BranchInst(bbFindNext);
|
||||||
|
|
||||||
ctx->SetCurrentBasicBlock(bbFindNext); {
|
ctx->SetCurrentBasicBlock(bbFindNext); {
|
||||||
// Load the bitmask of the lanes left to be processed
|
// Load the bitmask of the lanes left to be processed
|
||||||
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
||||||
|
|
||||||
// Find the index of the first set bit in the mask
|
// Find the index of the first set bit in the mask
|
||||||
llvm::Function *ctlzFunc =
|
llvm::Function *ctlzFunc =
|
||||||
m->module->getFunction("__count_trailing_zeros_i64");
|
m->module->getFunction("__count_trailing_zeros_i64");
|
||||||
Assert(ctlzFunc != NULL);
|
Assert(ctlzFunc != NULL);
|
||||||
llvm::Value *firstSet = ctx->CallInst(ctlzFunc, NULL, remainingBits,
|
llvm::Value *firstSet = ctx->CallInst(ctlzFunc, NULL, remainingBits,
|
||||||
@@ -1993,20 +1993,20 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// math...)
|
// math...)
|
||||||
|
|
||||||
// Get the "program index" vector value
|
// Get the "program index" vector value
|
||||||
llvm::Value *programIndex =
|
llvm::Value *programIndex =
|
||||||
llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
llvm::UndefValue::get(LLVMTypes::Int32VectorType);
|
||||||
for (int i = 0; i < g->target.vectorWidth; ++i)
|
for (int i = 0; i < g->target.vectorWidth; ++i)
|
||||||
programIndex = ctx->InsertInst(programIndex, LLVMInt32(i), i,
|
programIndex = ctx->InsertInst(programIndex, LLVMInt32(i), i,
|
||||||
"prog_index");
|
"prog_index");
|
||||||
|
|
||||||
// And smear the current lane out to a vector
|
// And smear the current lane out to a vector
|
||||||
llvm::Value *firstSet32 =
|
llvm::Value *firstSet32 =
|
||||||
ctx->TruncInst(firstSet, LLVMTypes::Int32Type, "first_set32");
|
ctx->TruncInst(firstSet, LLVMTypes::Int32Type, "first_set32");
|
||||||
llvm::Value *firstSet32Smear = ctx->SmearUniform(firstSet32);
|
llvm::Value *firstSet32Smear = ctx->SmearUniform(firstSet32);
|
||||||
|
|
||||||
// Now set the execution mask based on doing a vector compare of
|
// Now set the execution mask based on doing a vector compare of
|
||||||
// these two
|
// these two
|
||||||
llvm::Value *iterMask =
|
llvm::Value *iterMask =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
|
||||||
firstSet32Smear, programIndex);
|
firstSet32Smear, programIndex);
|
||||||
iterMask = ctx->I1VecToBoolVec(iterMask);
|
iterMask = ctx->I1VecToBoolVec(iterMask);
|
||||||
@@ -2015,12 +2015,12 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
|
|
||||||
// Also update the bitvector of lanes left to turn off the bit for
|
// Also update the bitvector of lanes left to turn off the bit for
|
||||||
// the lane we're about to run.
|
// the lane we're about to run.
|
||||||
llvm::Value *setMask =
|
llvm::Value *setMask =
|
||||||
ctx->BinaryOperator(llvm::Instruction::Shl, LLVMInt64(1),
|
ctx->BinaryOperator(llvm::Instruction::Shl, LLVMInt64(1),
|
||||||
firstSet, "set_mask");
|
firstSet, "set_mask");
|
||||||
llvm::Value *notSetMask = ctx->NotOperator(setMask);
|
llvm::Value *notSetMask = ctx->NotOperator(setMask);
|
||||||
llvm::Value *newRemaining =
|
llvm::Value *newRemaining =
|
||||||
ctx->BinaryOperator(llvm::Instruction::And, remainingBits,
|
ctx->BinaryOperator(llvm::Instruction::And, remainingBits,
|
||||||
notSetMask, "new_remaining");
|
notSetMask, "new_remaining");
|
||||||
ctx->StoreInst(newRemaining, maskBitsPtr);
|
ctx->StoreInst(newRemaining, maskBitsPtr);
|
||||||
|
|
||||||
@@ -2046,7 +2046,7 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// the loop that jumps to the end, see if there are any lanes left
|
// the loop that jumps to the end, see if there are any lanes left
|
||||||
// to be processed.
|
// to be processed.
|
||||||
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
||||||
llvm::Value *nonZero =
|
llvm::Value *nonZero =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
|
||||||
remainingBits, LLVMInt64(0), "remaining_ne_zero");
|
remainingBits, LLVMInt64(0), "remaining_ne_zero");
|
||||||
ctx->BranchInst(bbFindNext, bbDone, nonZero);
|
ctx->BranchInst(bbFindNext, bbDone, nonZero);
|
||||||
@@ -2102,8 +2102,8 @@ ForeachActiveStmt::EstimateCost() const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// ForeachUniqueStmt
|
// ForeachUniqueStmt
|
||||||
|
|
||||||
ForeachUniqueStmt::ForeachUniqueStmt(const char *iterName, Expr *e,
|
ForeachUniqueStmt::ForeachUniqueStmt(const char *iterName, Expr *e,
|
||||||
Stmt *s, SourcePos pos)
|
Stmt *s, SourcePos pos)
|
||||||
: Stmt(pos) {
|
: Stmt(pos) {
|
||||||
sym = m->symbolTable->LookupVariable(iterName);
|
sym = m->symbolTable->LookupVariable(iterName);
|
||||||
expr = e;
|
expr = e;
|
||||||
@@ -2113,7 +2113,7 @@ ForeachUniqueStmt::ForeachUniqueStmt(const char *iterName, Expr *e,
|
|||||||
|
|
||||||
void
|
void
|
||||||
ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// First, allocate local storage for the symbol that we'll use for the
|
// First, allocate local storage for the symbol that we'll use for the
|
||||||
@@ -2167,7 +2167,7 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
llvm::VectorType *llvmExprType;
|
llvm::VectorType *llvmExprType;
|
||||||
if (exprValue == NULL ||
|
if (exprValue == NULL ||
|
||||||
(exprType = expr->GetType()) == NULL ||
|
(exprType = expr->GetType()) == NULL ||
|
||||||
(llvmExprType =
|
(llvmExprType =
|
||||||
llvm::dyn_cast<llvm::VectorType>(exprValue->getType())) == NULL) {
|
llvm::dyn_cast<llvm::VectorType>(exprValue->getType())) == NULL) {
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return;
|
return;
|
||||||
@@ -2179,13 +2179,13 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
|
|
||||||
// Onward to find the first set of lanes to run the loop for
|
// Onward to find the first set of lanes to run the loop for
|
||||||
ctx->BranchInst(bbFindNext);
|
ctx->BranchInst(bbFindNext);
|
||||||
|
|
||||||
ctx->SetCurrentBasicBlock(bbFindNext); {
|
ctx->SetCurrentBasicBlock(bbFindNext); {
|
||||||
// Load the bitmask of the lanes left to be processed
|
// Load the bitmask of the lanes left to be processed
|
||||||
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
||||||
|
|
||||||
// Find the index of the first set bit in the mask
|
// Find the index of the first set bit in the mask
|
||||||
llvm::Function *ctlzFunc =
|
llvm::Function *ctlzFunc =
|
||||||
m->module->getFunction("__count_trailing_zeros_i64");
|
m->module->getFunction("__count_trailing_zeros_i64");
|
||||||
Assert(ctlzFunc != NULL);
|
Assert(ctlzFunc != NULL);
|
||||||
llvm::Value *firstSet = ctx->CallInst(ctlzFunc, NULL, remainingBits,
|
llvm::Value *firstSet = ctx->CallInst(ctlzFunc, NULL, remainingBits,
|
||||||
@@ -2193,7 +2193,7 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
|
|
||||||
// And load the corresponding element value from the temporary
|
// And load the corresponding element value from the temporary
|
||||||
// memory storing the value of the varying expr.
|
// memory storing the value of the varying expr.
|
||||||
llvm::Value *uniqueValuePtr =
|
llvm::Value *uniqueValuePtr =
|
||||||
ctx->GetElementPtrInst(exprMem, LLVMInt64(0), firstSet, exprPtrType,
|
ctx->GetElementPtrInst(exprMem, LLVMInt64(0), firstSet, exprPtrType,
|
||||||
"unique_index_ptr");
|
"unique_index_ptr");
|
||||||
llvm::Value *uniqueValue = ctx->LoadInst(uniqueValuePtr, "unique_value");
|
llvm::Value *uniqueValue = ctx->LoadInst(uniqueValuePtr, "unique_value");
|
||||||
@@ -2215,16 +2215,16 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
llvm::Value *uniqueSmear = ctx->SmearUniform(uniqueValue, "unique_smear");
|
llvm::Value *uniqueSmear = ctx->SmearUniform(uniqueValue, "unique_smear");
|
||||||
llvm::Value *matchingLanes = NULL;
|
llvm::Value *matchingLanes = NULL;
|
||||||
if (uniqueValue->getType()->isFloatingPointTy())
|
if (uniqueValue->getType()->isFloatingPointTy())
|
||||||
matchingLanes =
|
matchingLanes =
|
||||||
ctx->CmpInst(llvm::Instruction::FCmp, llvm::CmpInst::FCMP_OEQ,
|
ctx->CmpInst(llvm::Instruction::FCmp, llvm::CmpInst::FCMP_OEQ,
|
||||||
uniqueSmear, exprValue, "matching_lanes");
|
uniqueSmear, exprValue, "matching_lanes");
|
||||||
else
|
else
|
||||||
matchingLanes =
|
matchingLanes =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
|
||||||
uniqueSmear, exprValue, "matching_lanes");
|
uniqueSmear, exprValue, "matching_lanes");
|
||||||
matchingLanes = ctx->I1VecToBoolVec(matchingLanes);
|
matchingLanes = ctx->I1VecToBoolVec(matchingLanes);
|
||||||
|
|
||||||
llvm::Value *loopMask =
|
llvm::Value *loopMask =
|
||||||
ctx->BinaryOperator(llvm::Instruction::And, oldMask, matchingLanes,
|
ctx->BinaryOperator(llvm::Instruction::And, oldMask, matchingLanes,
|
||||||
"foreach_unique_loop_mask");
|
"foreach_unique_loop_mask");
|
||||||
ctx->SetInternalMask(loopMask);
|
ctx->SetInternalMask(loopMask);
|
||||||
@@ -2234,8 +2234,8 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// remainingBits &= ~movmsk(current mask)
|
// remainingBits &= ~movmsk(current mask)
|
||||||
llvm::Value *loopMaskMM = ctx->LaneMask(loopMask);
|
llvm::Value *loopMaskMM = ctx->LaneMask(loopMask);
|
||||||
llvm::Value *notLoopMaskMM = ctx->NotOperator(loopMaskMM);
|
llvm::Value *notLoopMaskMM = ctx->NotOperator(loopMaskMM);
|
||||||
llvm::Value *newRemaining =
|
llvm::Value *newRemaining =
|
||||||
ctx->BinaryOperator(llvm::Instruction::And, remainingBits,
|
ctx->BinaryOperator(llvm::Instruction::And, remainingBits,
|
||||||
notLoopMaskMM, "new_remaining");
|
notLoopMaskMM, "new_remaining");
|
||||||
ctx->StoreInst(newRemaining, maskBitsPtr);
|
ctx->StoreInst(newRemaining, maskBitsPtr);
|
||||||
|
|
||||||
@@ -2260,7 +2260,7 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// to be processed.
|
// to be processed.
|
||||||
ctx->RestoreContinuedLanes();
|
ctx->RestoreContinuedLanes();
|
||||||
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
llvm::Value *remainingBits = ctx->LoadInst(maskBitsPtr, "remaining_bits");
|
||||||
llvm::Value *nonZero =
|
llvm::Value *nonZero =
|
||||||
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
|
ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
|
||||||
remainingBits, LLVMInt64(0), "remaining_ne_zero");
|
remainingBits, LLVMInt64(0), "remaining_ne_zero");
|
||||||
ctx->BranchInst(bbFindNext, bbDone, nonZero);
|
ctx->BranchInst(bbFindNext, bbDone, nonZero);
|
||||||
@@ -2359,7 +2359,7 @@ lCheckMask(Stmt *stmts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CaseStmt::CaseStmt(int v, Stmt *s, SourcePos pos)
|
CaseStmt::CaseStmt(int v, Stmt *s, SourcePos pos)
|
||||||
: Stmt(pos), value(v) {
|
: Stmt(pos), value(v) {
|
||||||
stmts = s;
|
stmts = s;
|
||||||
}
|
}
|
||||||
@@ -2397,7 +2397,7 @@ CaseStmt::EstimateCost() const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// DefaultStmt
|
// DefaultStmt
|
||||||
|
|
||||||
DefaultStmt::DefaultStmt(Stmt *s, SourcePos pos)
|
DefaultStmt::DefaultStmt(Stmt *s, SourcePos pos)
|
||||||
: Stmt(pos) {
|
: Stmt(pos) {
|
||||||
stmts = s;
|
stmts = s;
|
||||||
}
|
}
|
||||||
@@ -2435,7 +2435,7 @@ DefaultStmt::EstimateCost() const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// SwitchStmt
|
// SwitchStmt
|
||||||
|
|
||||||
SwitchStmt::SwitchStmt(Expr *e, Stmt *s, SourcePos pos)
|
SwitchStmt::SwitchStmt(Expr *e, Stmt *s, SourcePos pos)
|
||||||
: Stmt(pos) {
|
: Stmt(pos) {
|
||||||
expr = e;
|
expr = e;
|
||||||
stmts = s;
|
stmts = s;
|
||||||
@@ -2447,9 +2447,9 @@ SwitchStmt::SwitchStmt(Expr *e, Stmt *s, SourcePos pos)
|
|||||||
structure to record all of the 'case' and 'default' statements after the
|
structure to record all of the 'case' and 'default' statements after the
|
||||||
"switch". */
|
"switch". */
|
||||||
struct SwitchVisitInfo {
|
struct SwitchVisitInfo {
|
||||||
SwitchVisitInfo(FunctionEmitContext *c) {
|
SwitchVisitInfo(FunctionEmitContext *c) {
|
||||||
ctx = c;
|
ctx = c;
|
||||||
defaultBlock = NULL;
|
defaultBlock = NULL;
|
||||||
lastBlock = NULL;
|
lastBlock = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2491,11 +2491,11 @@ lSwitchASTPreVisit(ASTNode *node, void *d) {
|
|||||||
// already
|
// already
|
||||||
for (int i = 0; i < (int)svi->caseBlocks.size(); ++i) {
|
for (int i = 0; i < (int)svi->caseBlocks.size(); ++i) {
|
||||||
if (svi->caseBlocks[i].first == cs->value) {
|
if (svi->caseBlocks[i].first == cs->value) {
|
||||||
Error(cs->pos, "Duplicate case value \"%d\".", cs->value);
|
Error(cs->pos, "Duplicate case value \"%d\".", cs->value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise create a new basic block for the code following this
|
// Otherwise create a new basic block for the code following this
|
||||||
// 'case' statement and record the mappign between the case label
|
// 'case' statement and record the mappign between the case label
|
||||||
// value and the basic block
|
// value and the basic block
|
||||||
@@ -2689,14 +2689,14 @@ UnmaskedStmt::EstimateCost() const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// ReturnStmt
|
// ReturnStmt
|
||||||
|
|
||||||
ReturnStmt::ReturnStmt(Expr *e, SourcePos p)
|
ReturnStmt::ReturnStmt(Expr *e, SourcePos p)
|
||||||
: Stmt(p), expr(e) {
|
: Stmt(p), expr(e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ReturnStmt::EmitCode(FunctionEmitContext *ctx) const {
|
ReturnStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ctx->InForeachLoop()) {
|
if (ctx->InForeachLoop()) {
|
||||||
@@ -2756,7 +2756,7 @@ ReturnStmt::Print(int indent) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// GotoStmt
|
// GotoStmt
|
||||||
|
|
||||||
GotoStmt::GotoStmt(const char *l, SourcePos gotoPos, SourcePos ip)
|
GotoStmt::GotoStmt(const char *l, SourcePos gotoPos, SourcePos ip)
|
||||||
: Stmt(gotoPos) {
|
: Stmt(gotoPos) {
|
||||||
label = l;
|
label = l;
|
||||||
identifierPos = ip;
|
identifierPos = ip;
|
||||||
@@ -2765,7 +2765,7 @@ GotoStmt::GotoStmt(const char *l, SourcePos gotoPos, SourcePos ip)
|
|||||||
|
|
||||||
void
|
void
|
||||||
GotoStmt::EmitCode(FunctionEmitContext *ctx) const {
|
GotoStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ctx->VaryingCFDepth() > 0) {
|
if (ctx->VaryingCFDepth() > 0) {
|
||||||
@@ -2793,7 +2793,7 @@ GotoStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Label wasn't found. Emit an error */
|
/* Label wasn't found. Emit an error */
|
||||||
Error(identifierPos,
|
Error(identifierPos,
|
||||||
"No label named \"%s\" found in current function.%s",
|
"No label named \"%s\" found in current function.%s",
|
||||||
label.c_str(), match_output.c_str());
|
label.c_str(), match_output.c_str());
|
||||||
|
|
||||||
@@ -2832,7 +2832,7 @@ GotoStmt::EstimateCost() const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// LabeledStmt
|
// LabeledStmt
|
||||||
|
|
||||||
LabeledStmt::LabeledStmt(const char *n, Stmt *s, SourcePos p)
|
LabeledStmt::LabeledStmt(const char *n, Stmt *s, SourcePos p)
|
||||||
: Stmt(p) {
|
: Stmt(p) {
|
||||||
name = n;
|
name = n;
|
||||||
stmt = s;
|
stmt = s;
|
||||||
@@ -2934,7 +2934,7 @@ StmtList::Print(int indent) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// PrintStmt
|
// PrintStmt
|
||||||
|
|
||||||
PrintStmt::PrintStmt(const std::string &f, Expr *v, SourcePos p)
|
PrintStmt::PrintStmt(const std::string &f, Expr *v, SourcePos p)
|
||||||
: Stmt(p), format(f), values(v) {
|
: Stmt(p), format(f), values(v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2995,11 +2995,11 @@ lProcessPrintArg(Expr *expr, FunctionEmitContext *ctx, std::string &argTypes) {
|
|||||||
Type::Equal(baseType, AtomicType::UniformInt16) ||
|
Type::Equal(baseType, AtomicType::UniformInt16) ||
|
||||||
Type::Equal(baseType, AtomicType::UniformUInt16)) {
|
Type::Equal(baseType, AtomicType::UniformUInt16)) {
|
||||||
expr = new TypeCastExpr(type->IsUniformType() ? AtomicType::UniformInt32 :
|
expr = new TypeCastExpr(type->IsUniformType() ? AtomicType::UniformInt32 :
|
||||||
AtomicType::VaryingInt32,
|
AtomicType::VaryingInt32,
|
||||||
expr, expr->pos);
|
expr, expr->pos);
|
||||||
type = expr->GetType();
|
type = expr->GetType();
|
||||||
}
|
}
|
||||||
|
|
||||||
char t = lEncodeType(type->GetAsNonConstType());
|
char t = lEncodeType(type->GetAsNonConstType());
|
||||||
if (t == '\0') {
|
if (t == '\0') {
|
||||||
Error(expr->pos, "Only atomic types are allowed in print statements; "
|
Error(expr->pos, "Only atomic types are allowed in print statements; "
|
||||||
@@ -3030,7 +3030,7 @@ lProcessPrintArg(Expr *expr, FunctionEmitContext *ctx, std::string &argTypes) {
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
|
PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctx->SetDebugPos(pos);
|
ctx->SetDebugPos(pos);
|
||||||
@@ -3039,7 +3039,7 @@ PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// in the code emitted below
|
// in the code emitted below
|
||||||
//
|
//
|
||||||
// 1. the format string
|
// 1. the format string
|
||||||
// 2. a string encoding the types of the values being printed,
|
// 2. a string encoding the types of the values being printed,
|
||||||
// one character per value
|
// one character per value
|
||||||
// 3. the number of running program instances (i.e. the target's
|
// 3. the number of running program instances (i.e. the target's
|
||||||
// vector width)
|
// vector width)
|
||||||
@@ -3049,7 +3049,7 @@ PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
std::string argTypes;
|
std::string argTypes;
|
||||||
|
|
||||||
if (values == NULL) {
|
if (values == NULL) {
|
||||||
llvm::Type *ptrPtrType =
|
llvm::Type *ptrPtrType =
|
||||||
llvm::PointerType::get(LLVMTypes::VoidPointerType, 0);
|
llvm::PointerType::get(LLVMTypes::VoidPointerType, 0);
|
||||||
args[4] = llvm::Constant::getNullValue(ptrPtrType);
|
args[4] = llvm::Constant::getNullValue(ptrPtrType);
|
||||||
}
|
}
|
||||||
@@ -3060,14 +3060,14 @@ PrintStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
ExprList *elist = dynamic_cast<ExprList *>(values);
|
ExprList *elist = dynamic_cast<ExprList *>(values);
|
||||||
int nArgs = elist ? elist->exprs.size() : 1;
|
int nArgs = elist ? elist->exprs.size() : 1;
|
||||||
|
|
||||||
// Allocate space for the array of pointers to values to be printed
|
// Allocate space for the array of pointers to values to be printed
|
||||||
llvm::Type *argPtrArrayType =
|
llvm::Type *argPtrArrayType =
|
||||||
llvm::ArrayType::get(LLVMTypes::VoidPointerType, nArgs);
|
llvm::ArrayType::get(LLVMTypes::VoidPointerType, nArgs);
|
||||||
llvm::Value *argPtrArray = ctx->AllocaInst(argPtrArrayType,
|
llvm::Value *argPtrArray = ctx->AllocaInst(argPtrArrayType,
|
||||||
"print_arg_ptrs");
|
"print_arg_ptrs");
|
||||||
// Store the array pointer as a void **, which is what __do_print()
|
// Store the array pointer as a void **, which is what __do_print()
|
||||||
// expects
|
// expects
|
||||||
args[4] = ctx->BitCastInst(argPtrArray,
|
args[4] = ctx->BitCastInst(argPtrArray,
|
||||||
llvm::PointerType::get(LLVMTypes::VoidPointerType, 0));
|
llvm::PointerType::get(LLVMTypes::VoidPointerType, 0));
|
||||||
|
|
||||||
// Now, for each of the arguments, emit code to evaluate its value
|
// Now, for each of the arguments, emit code to evaluate its value
|
||||||
@@ -3131,14 +3131,14 @@ PrintStmt::EstimateCost() const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// AssertStmt
|
// AssertStmt
|
||||||
|
|
||||||
AssertStmt::AssertStmt(const std::string &msg, Expr *e, SourcePos p)
|
AssertStmt::AssertStmt(const std::string &msg, Expr *e, SourcePos p)
|
||||||
: Stmt(p), message(msg), expr(e) {
|
: Stmt(p), message(msg), expr(e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AssertStmt::EmitCode(FunctionEmitContext *ctx) const {
|
AssertStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Type *type;
|
const Type *type;
|
||||||
@@ -3151,14 +3151,14 @@ AssertStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
|
|
||||||
// The actual functionality to do the check and then handle falure is
|
// The actual functionality to do the check and then handle falure is
|
||||||
// done via a builtin written in bitcode in builtins/util.m4.
|
// done via a builtin written in bitcode in builtins/util.m4.
|
||||||
llvm::Function *assertFunc =
|
llvm::Function *assertFunc =
|
||||||
isUniform ? m->module->getFunction("__do_assert_uniform") :
|
isUniform ? m->module->getFunction("__do_assert_uniform") :
|
||||||
m->module->getFunction("__do_assert_varying");
|
m->module->getFunction("__do_assert_varying");
|
||||||
AssertPos(pos, assertFunc != NULL);
|
AssertPos(pos, assertFunc != NULL);
|
||||||
|
|
||||||
char *errorString;
|
char *errorString;
|
||||||
if (asprintf(&errorString, "%s:%d:%d: Assertion failed: %s",
|
if (asprintf(&errorString, "%s:%d:%d: Assertion failed: %s",
|
||||||
pos.name, pos.first_line, pos.first_column,
|
pos.name, pos.first_line, pos.first_column,
|
||||||
message.c_str()) == -1) {
|
message.c_str()) == -1) {
|
||||||
Error(pos, "Fatal error when generating assert string: asprintf() "
|
Error(pos, "Fatal error when generating assert string: asprintf() "
|
||||||
"unable to allocate memory!");
|
"unable to allocate memory!");
|
||||||
@@ -3191,8 +3191,8 @@ AssertStmt::TypeCheck() {
|
|||||||
const Type *type;
|
const Type *type;
|
||||||
if (expr && (type = expr->GetType()) != NULL) {
|
if (expr && (type = expr->GetType()) != NULL) {
|
||||||
bool isUniform = type->IsUniformType();
|
bool isUniform = type->IsUniformType();
|
||||||
expr = TypeConvertExpr(expr, isUniform ? AtomicType::UniformBool :
|
expr = TypeConvertExpr(expr, isUniform ? AtomicType::UniformBool :
|
||||||
AtomicType::VaryingBool,
|
AtomicType::VaryingBool,
|
||||||
"\"assert\" statement");
|
"\"assert\" statement");
|
||||||
if (expr == NULL)
|
if (expr == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -3218,7 +3218,7 @@ DeleteStmt::DeleteStmt(Expr *e, SourcePos p)
|
|||||||
|
|
||||||
void
|
void
|
||||||
DeleteStmt::EmitCode(FunctionEmitContext *ctx) const {
|
DeleteStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||||
if (!ctx->GetCurrentBasicBlock())
|
if (!ctx->GetCurrentBasicBlock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Type *exprType;
|
const Type *exprType;
|
||||||
|
|||||||
22
stmt.h
22
stmt.h
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file stmt.h
|
/** @file stmt.h
|
||||||
@@ -84,8 +84,8 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
struct VariableDeclaration {
|
struct VariableDeclaration {
|
||||||
VariableDeclaration(Symbol *s = NULL, Expr *i = NULL) {
|
VariableDeclaration(Symbol *s = NULL, Expr *i = NULL) {
|
||||||
sym = s; init = i;
|
sym = s; init = i;
|
||||||
}
|
}
|
||||||
Symbol *sym;
|
Symbol *sym;
|
||||||
Expr *init;
|
Expr *init;
|
||||||
@@ -137,12 +137,12 @@ private:
|
|||||||
'false' blocks. */
|
'false' blocks. */
|
||||||
const bool doAllCheck;
|
const bool doAllCheck;
|
||||||
|
|
||||||
void emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
void emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||||
llvm::Value *test) const;
|
llvm::Value *test) const;
|
||||||
void emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *test) const;
|
void emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *test) const;
|
||||||
void emitMaskAllOn(FunctionEmitContext *ctx,
|
void emitMaskAllOn(FunctionEmitContext *ctx,
|
||||||
llvm::Value *test, llvm::BasicBlock *bDone) const;
|
llvm::Value *test, llvm::BasicBlock *bDone) const;
|
||||||
void emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
void emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
||||||
llvm::Value *test, llvm::BasicBlock *bDone) const;
|
llvm::Value *test, llvm::BasicBlock *bDone) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
class DoStmt : public Stmt {
|
class DoStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
DoStmt(Expr *testExpr, Stmt *bodyStmts, bool doCoherentCheck,
|
DoStmt(Expr *testExpr, Stmt *bodyStmts, bool doCoherentCheck,
|
||||||
SourcePos pos);
|
SourcePos pos);
|
||||||
|
|
||||||
void EmitCode(FunctionEmitContext *ctx) const;
|
void EmitCode(FunctionEmitContext *ctx) const;
|
||||||
@@ -227,9 +227,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
class ForeachStmt : public Stmt {
|
class ForeachStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
ForeachStmt(const std::vector<Symbol *> &loopVars,
|
ForeachStmt(const std::vector<Symbol *> &loopVars,
|
||||||
const std::vector<Expr *> &startExprs,
|
const std::vector<Expr *> &startExprs,
|
||||||
const std::vector<Expr *> &endExprs,
|
const std::vector<Expr *> &endExprs,
|
||||||
Stmt *bodyStatements, bool tiled, SourcePos pos);
|
Stmt *bodyStatements, bool tiled, SourcePos pos);
|
||||||
|
|
||||||
void EmitCode(FunctionEmitContext *ctx) const;
|
void EmitCode(FunctionEmitContext *ctx) const;
|
||||||
@@ -283,7 +283,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
class UnmaskedStmt : public Stmt {
|
class UnmaskedStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
@@ -493,7 +493,7 @@ public:
|
|||||||
Expr *expr;
|
Expr *expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Stmt *CreateForeachActiveStmt(Symbol *iterSym, Stmt *stmts,
|
extern Stmt *CreateForeachActiveStmt(Symbol *iterSym, Stmt *stmts,
|
||||||
SourcePos pos);
|
SourcePos pos);
|
||||||
|
|
||||||
#endif // ISPC_STMT_H
|
#endif // ISPC_STMT_H
|
||||||
|
|||||||
18
sym.cpp
18
sym.cpp
@@ -28,11 +28,11 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file sym.cpp
|
/** @file sym.cpp
|
||||||
@brief file with definitions for symbol and symbol table classes.
|
@brief file with definitions for symbol and symbol table classes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sym.h"
|
#include "sym.h"
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Symbol
|
// Symbol
|
||||||
|
|
||||||
Symbol::Symbol(const std::string &n, SourcePos p, const Type *t,
|
Symbol::Symbol(const std::string &n, SourcePos p, const Type *t,
|
||||||
StorageClass sc)
|
StorageClass sc)
|
||||||
: pos(p), name(n) {
|
: pos(p), name(n) {
|
||||||
storagePtr = NULL;
|
storagePtr = NULL;
|
||||||
function = exportedFunction = NULL;
|
function = exportedFunction = NULL;
|
||||||
@@ -72,7 +72,7 @@ SymbolTable::~SymbolTable() {
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SymbolTable::PushScope() {
|
SymbolTable::PushScope() {
|
||||||
SymbolMapType *sm;
|
SymbolMapType *sm;
|
||||||
if (freeSymbolMaps.size() > 0) {
|
if (freeSymbolMaps.size() > 0) {
|
||||||
sm = freeSymbolMaps.back();
|
sm = freeSymbolMaps.back();
|
||||||
@@ -87,7 +87,7 @@ SymbolTable::PushScope() {
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SymbolTable::PopScope() {
|
SymbolTable::PopScope() {
|
||||||
Assert(variables.size() > 1);
|
Assert(variables.size() > 1);
|
||||||
freeSymbolMaps.push_back(variables.back());
|
freeSymbolMaps.push_back(variables.back());
|
||||||
variables.pop_back();
|
variables.pop_back();
|
||||||
@@ -105,14 +105,14 @@ SymbolTable::AddVariable(Symbol *symbol) {
|
|||||||
if (i == (int)variables.size()-1) {
|
if (i == (int)variables.size()-1) {
|
||||||
// If a symbol of the same name was declared in the
|
// If a symbol of the same name was declared in the
|
||||||
// same scope, it's an error.
|
// same scope, it's an error.
|
||||||
Error(symbol->pos, "Ignoring redeclaration of symbol \"%s\".",
|
Error(symbol->pos, "Ignoring redeclaration of symbol \"%s\".",
|
||||||
symbol->name.c_str());
|
symbol->name.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Otherwise it's just shadowing something else, which
|
// Otherwise it's just shadowing something else, which
|
||||||
// is legal but dangerous..
|
// is legal but dangerous..
|
||||||
Warning(symbol->pos,
|
Warning(symbol->pos,
|
||||||
"Symbol \"%s\" shadows symbol declared in outer scope.",
|
"Symbol \"%s\" shadows symbol declared in outer scope.",
|
||||||
symbol->name.c_str());
|
symbol->name.c_str());
|
||||||
(*variables.back())[symbol->name] = symbol;
|
(*variables.back())[symbol->name] = symbol;
|
||||||
@@ -308,7 +308,7 @@ SymbolTable::Print() {
|
|||||||
for (iter = sm.begin(); iter != sm.end(); ++iter) {
|
for (iter = sm.begin(); iter != sm.end(); ++iter) {
|
||||||
fprintf(stderr, "%*c", depth, ' ');
|
fprintf(stderr, "%*c", depth, ' ');
|
||||||
Symbol *sym = iter->second;
|
Symbol *sym = iter->second;
|
||||||
fprintf(stderr, "%s [%s]", sym->name.c_str(),
|
fprintf(stderr, "%s [%s]", sym->name.c_str(),
|
||||||
sym->type->GetString().c_str());
|
sym->type->GetString().c_str());
|
||||||
}
|
}
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
|||||||
48
sym.h
48
sym.h
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file sym.h
|
/** @file sym.h
|
||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
location in memory.) */
|
location in memory.) */
|
||||||
llvm::Function *function; /*!< For symbols that represent functions,
|
llvm::Function *function; /*!< For symbols that represent functions,
|
||||||
this stores the LLVM Function value for
|
this stores the LLVM Function value for
|
||||||
the symbol once it has been created. */
|
the symbol once it has been created. */
|
||||||
llvm::Function *exportedFunction;
|
llvm::Function *exportedFunction;
|
||||||
/*!< For symbols that represent functions with
|
/*!< For symbols that represent functions with
|
||||||
'export' qualifiers, this points to the LLVM
|
'export' qualifiers, this points to the LLVM
|
||||||
@@ -91,18 +91,18 @@ public:
|
|||||||
struct types. For cases like these, ConstExpr is NULL,
|
struct types. For cases like these, ConstExpr is NULL,
|
||||||
though for all const symbols, the value pointed to by the
|
though for all const symbols, the value pointed to by the
|
||||||
storagePtr member will be its constant value. (This
|
storagePtr member will be its constant value. (This
|
||||||
messiness is due to needing an ispc ConstExpr for the early
|
messiness is due to needing an ispc ConstExpr for the early
|
||||||
constant folding optimizations). */
|
constant folding optimizations). */
|
||||||
StorageClass storageClass;/*!< Records the storage class (if any) provided with the
|
StorageClass storageClass;/*!< Records the storage class (if any) provided with the
|
||||||
symbol's declaration. */
|
symbol's declaration. */
|
||||||
int varyingCFDepth; /*!< This member records the number of levels of nested 'varying'
|
int varyingCFDepth; /*!< This member records the number of levels of nested 'varying'
|
||||||
control flow within which the symbol was declared. Having
|
control flow within which the symbol was declared. Having
|
||||||
this value available makes it possible to avoid performing
|
this value available makes it possible to avoid performing
|
||||||
masked stores when modifying the symbol's value when the
|
masked stores when modifying the symbol's value when the
|
||||||
store is done at the same 'varying' control flow depth as
|
store is done at the same 'varying' control flow depth as
|
||||||
the one where the symbol was originally declared. */
|
the one where the symbol was originally declared. */
|
||||||
const Function *parentFunction;
|
const Function *parentFunction;
|
||||||
/*!< For symbols that are parameters to functions or are
|
/*!< For symbols that are parameters to functions or are
|
||||||
variables declared inside functions, this gives the
|
variables declared inside functions, this gives the
|
||||||
function they're in. */
|
function they're in. */
|
||||||
};
|
};
|
||||||
@@ -130,7 +130,7 @@ public:
|
|||||||
|
|
||||||
/** For each scope started by a call to SymbolTable::PushScope(), there
|
/** For each scope started by a call to SymbolTable::PushScope(), there
|
||||||
must be a matching call to SymbolTable::PopScope() at the end of
|
must be a matching call to SymbolTable::PopScope() at the end of
|
||||||
that scope. */
|
that scope. */
|
||||||
void PopScope();
|
void PopScope();
|
||||||
|
|
||||||
/** Adds the given variable symbol to the symbol table.
|
/** Adds the given variable symbol to the symbol table.
|
||||||
@@ -147,7 +147,7 @@ public:
|
|||||||
returning the first match found.
|
returning the first match found.
|
||||||
|
|
||||||
@param name The name of the variable to be searched for.
|
@param name The name of the variable to be searched for.
|
||||||
@return A pointer to the Symbol, if a match is found. NULL if no
|
@return A pointer to the Symbol, if a match is found. NULL if no
|
||||||
Symbol with the given name is in the symbol table. */
|
Symbol with the given name is in the symbol table. */
|
||||||
Symbol *LookupVariable(const char *name);
|
Symbol *LookupVariable(const char *name);
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ public:
|
|||||||
be returned in the provided vector and it's up the the caller to
|
be returned in the provided vector and it's up the the caller to
|
||||||
resolve which one (if any) to use. Returns true if any matches
|
resolve which one (if any) to use. Returns true if any matches
|
||||||
were found. */
|
were found. */
|
||||||
bool LookupFunction(const char *name,
|
bool LookupFunction(const char *name,
|
||||||
std::vector<Symbol *> *matches = NULL);
|
std::vector<Symbol *> *matches = NULL);
|
||||||
|
|
||||||
/** Looks for a function with the given name and type
|
/** Looks for a function with the given name and type
|
||||||
@@ -174,28 +174,28 @@ public:
|
|||||||
@return pointer to matching Symbol; NULL if none is found. */
|
@return pointer to matching Symbol; NULL if none is found. */
|
||||||
Symbol *LookupFunction(const char *name, const FunctionType *type);
|
Symbol *LookupFunction(const char *name, const FunctionType *type);
|
||||||
|
|
||||||
/** Returns all of the functions in the symbol table that match the given
|
/** Returns all of the functions in the symbol table that match the given
|
||||||
predicate.
|
predicate.
|
||||||
|
|
||||||
@param pred A unary predicate that returns true or false, given a Symbol
|
@param pred A unary predicate that returns true or false, given a Symbol
|
||||||
pointer, based on whether the symbol should be included in the returned
|
pointer, based on whether the symbol should be included in the returned
|
||||||
set of matches. It can either be a function, with signature
|
set of matches. It can either be a function, with signature
|
||||||
<tt>bool pred(const Symbol *s)</tt>, or a unary predicate object with
|
<tt>bool pred(const Symbol *s)</tt>, or a unary predicate object with
|
||||||
an <tt>bool operator()(const Symbol *)</tt> method.
|
an <tt>bool operator()(const Symbol *)</tt> method.
|
||||||
|
|
||||||
@param matches Pointer to a vector in which to return the matching
|
@param matches Pointer to a vector in which to return the matching
|
||||||
symbols.
|
symbols.
|
||||||
*/
|
*/
|
||||||
template <typename Predicate>
|
template <typename Predicate>
|
||||||
void GetMatchingFunctions(Predicate pred,
|
void GetMatchingFunctions(Predicate pred,
|
||||||
std::vector<Symbol *> *matches) const;
|
std::vector<Symbol *> *matches) const;
|
||||||
|
|
||||||
/** Returns all of the variable symbols in the symbol table that match
|
/** Returns all of the variable symbols in the symbol table that match
|
||||||
the given predicate. The predicate is defined as in the
|
the given predicate. The predicate is defined as in the
|
||||||
GetMatchingFunctions() method.
|
GetMatchingFunctions() method.
|
||||||
*/
|
*/
|
||||||
template <typename Predicate>
|
template <typename Predicate>
|
||||||
void GetMatchingVariables(Predicate pred,
|
void GetMatchingVariables(Predicate pred,
|
||||||
std::vector<Symbol *> *matches) const;
|
std::vector<Symbol *> *matches) const;
|
||||||
|
|
||||||
/** Adds the named type to the symbol table. This is used for both
|
/** Adds the named type to the symbol table. This is used for both
|
||||||
@@ -210,7 +210,7 @@ public:
|
|||||||
@param pos Position in source file where the type was named
|
@param pos Position in source file where the type was named
|
||||||
@return true if the named type was successfully added. False if a type
|
@return true if the named type was successfully added. False if a type
|
||||||
with the same name has already been defined.
|
with the same name has already been defined.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
bool AddType(const char *name, const Type *type, SourcePos pos);
|
bool AddType(const char *name, const Type *type, SourcePos pos);
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ public:
|
|||||||
const Type *RandomType();
|
const Type *RandomType();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> closestTypeMatch(const char *str,
|
std::vector<std::string> closestTypeMatch(const char *str,
|
||||||
bool structsVsEnums) const;
|
bool structsVsEnums) const;
|
||||||
|
|
||||||
/** This member variable holds one SymbolMap for each of the current
|
/** This member variable holds one SymbolMap for each of the current
|
||||||
@@ -278,7 +278,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
template <typename Predicate> void
|
template <typename Predicate> void
|
||||||
SymbolTable::GetMatchingFunctions(Predicate pred,
|
SymbolTable::GetMatchingFunctions(Predicate pred,
|
||||||
std::vector<Symbol *> *matches) const {
|
std::vector<Symbol *> *matches) const {
|
||||||
// Iterate through all function symbols and apply the given predicate.
|
// Iterate through all function symbols and apply the given predicate.
|
||||||
// If it returns true, add the Symbol * to the provided vector.
|
// If it returns true, add the Symbol * to the provided vector.
|
||||||
@@ -294,7 +294,7 @@ SymbolTable::GetMatchingFunctions(Predicate pred,
|
|||||||
|
|
||||||
|
|
||||||
template <typename Predicate> void
|
template <typename Predicate> void
|
||||||
SymbolTable::GetMatchingVariables(Predicate pred,
|
SymbolTable::GetMatchingVariables(Predicate pred,
|
||||||
std::vector<Symbol *> *matches) const {
|
std::vector<Symbol *> *matches) const {
|
||||||
for (unsigned int i = 0; i < variables.size(); ++i) {
|
for (unsigned int i = 0; i < variables.size(); ++i) {
|
||||||
SymbolMapType &sm = *(variables[i]);
|
SymbolMapType &sm = *(variables[i]);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
@@ -61,7 +61,7 @@ extern "C" {
|
|||||||
extern void f_duf(float *result, double *a, float b);
|
extern void f_duf(float *result, double *a, float b);
|
||||||
extern void f_di(float *result, double *a, int *b);
|
extern void f_di(float *result, double *a, int *b);
|
||||||
extern void result(float *val);
|
extern void result(float *val);
|
||||||
|
|
||||||
void ISPCLaunch(void **handlePtr, void *f, void *d, int);
|
void ISPCLaunch(void **handlePtr, void *f, void *d, int);
|
||||||
void ISPCSync(void *handle);
|
void ISPCSync(void *handle);
|
||||||
void *ISPCAlloc(void **handlePtr, int64_t size, int32_t alignment);
|
void *ISPCAlloc(void **handlePtr, int64_t size, int32_t alignment);
|
||||||
@@ -141,7 +141,7 @@ int main(int argc, char *argv[]) {
|
|||||||
f_di(returned_result, vdouble, vint2);
|
f_di(returned_result, vdouble, vint2);
|
||||||
#else
|
#else
|
||||||
#error "Unknown or unset TEST_SIG value"
|
#error "Unknown or unset TEST_SIG value"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float expected_result[64];
|
float expected_result[64];
|
||||||
memset(expected_result, 0, 64*sizeof(float));
|
memset(expected_result, 0, 64*sizeof(float));
|
||||||
@@ -155,7 +155,7 @@ int main(int argc, char *argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
#else
|
#else
|
||||||
printf("%s: value %d disagrees: returned %f [%a], expected %f [%a]\n",
|
printf("%s: value %d disagrees: returned %f [%a], expected %f [%a]\n",
|
||||||
argv[0], i, returned_result[i], returned_result[i],
|
argv[0], i, returned_result[i], returned_result[i],
|
||||||
expected_result[i], expected_result[i]);
|
expected_result[i], expected_result[i]);
|
||||||
++errors;
|
++errors;
|
||||||
#endif // EXPECT_FAILURE
|
#endif // EXPECT_FAILURE
|
||||||
|
|||||||
238
type.cpp
238
type.cpp
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file type.cpp
|
/** @file type.cpp
|
||||||
@@ -79,7 +79,7 @@ lShouldPrintName(const std::string &name) {
|
|||||||
|
|
||||||
/** Utility routine to create a llvm DIArray type of the given number of
|
/** Utility routine to create a llvm DIArray type of the given number of
|
||||||
the given element type. */
|
the given element type. */
|
||||||
static llvm::DIType
|
static llvm::DIType
|
||||||
lCreateDIArray(llvm::DIType eltType, int count) {
|
lCreateDIArray(llvm::DIType eltType, int count) {
|
||||||
int lowerBound = 0, upperBound = count-1;
|
int lowerBound = 0, upperBound = count-1;
|
||||||
|
|
||||||
@@ -125,9 +125,9 @@ Variability::GetString() const {
|
|||||||
std::string
|
std::string
|
||||||
Variability::MangleString() const {
|
Variability::MangleString() const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Uniform:
|
case Uniform:
|
||||||
return "un";
|
return "un";
|
||||||
case Varying:
|
case Varying:
|
||||||
return "vy";
|
return "vy";
|
||||||
case SOA: {
|
case SOA: {
|
||||||
char buf[32];
|
char buf[32];
|
||||||
@@ -189,11 +189,11 @@ const AtomicType *AtomicType::UniformDouble =
|
|||||||
new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Uniform, false);
|
new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingDouble =
|
const AtomicType *AtomicType::VaryingDouble =
|
||||||
new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Varying, false);
|
new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::Void =
|
const AtomicType *AtomicType::Void =
|
||||||
new AtomicType(TYPE_VOID, Variability::Uniform, false);
|
new AtomicType(TYPE_VOID, Variability::Uniform, false);
|
||||||
|
|
||||||
|
|
||||||
AtomicType::AtomicType(BasicType bt, Variability v, bool ic)
|
AtomicType::AtomicType(BasicType bt, Variability v, bool ic)
|
||||||
: Type(ATOMIC_TYPE), basicType(bt), variability(v), isConst(ic) {
|
: Type(ATOMIC_TYPE), basicType(bt), variability(v), isConst(ic) {
|
||||||
asOtherConstType = NULL;
|
asOtherConstType = NULL;
|
||||||
asUniformType = asVaryingType = NULL;
|
asUniformType = asVaryingType = NULL;
|
||||||
@@ -255,14 +255,14 @@ AtomicType::IsBoolType() const {
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AtomicType::IsConstType() const {
|
AtomicType::IsConstType() const {
|
||||||
return isConst;
|
return isConst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const AtomicType *
|
const AtomicType *
|
||||||
AtomicType::GetAsUnsignedType() const {
|
AtomicType::GetAsUnsignedType() const {
|
||||||
if (IsUnsignedType() == true)
|
if (IsUnsignedType() == true)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (IsIntType() == false)
|
if (IsIntType() == false)
|
||||||
@@ -286,9 +286,9 @@ AtomicType::GetAsUnsignedType() const {
|
|||||||
|
|
||||||
const AtomicType *
|
const AtomicType *
|
||||||
AtomicType::GetAsConstType() const {
|
AtomicType::GetAsConstType() const {
|
||||||
if (basicType == TYPE_VOID || isConst == true)
|
if (basicType == TYPE_VOID || isConst == true)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (asOtherConstType == NULL) {
|
if (asOtherConstType == NULL) {
|
||||||
asOtherConstType = new AtomicType(basicType, variability, true);
|
asOtherConstType = new AtomicType(basicType, variability, true);
|
||||||
asOtherConstType->asOtherConstType = this;
|
asOtherConstType->asOtherConstType = this;
|
||||||
@@ -299,7 +299,7 @@ AtomicType::GetAsConstType() const {
|
|||||||
|
|
||||||
const AtomicType *
|
const AtomicType *
|
||||||
AtomicType::GetAsNonConstType() const {
|
AtomicType::GetAsNonConstType() const {
|
||||||
if (basicType == TYPE_VOID || isConst == false)
|
if (basicType == TYPE_VOID || isConst == false)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (asOtherConstType == NULL) {
|
if (asOtherConstType == NULL) {
|
||||||
@@ -429,7 +429,7 @@ AtomicType::Mangle() const {
|
|||||||
std::string
|
std::string
|
||||||
AtomicType::GetCDeclaration(const std::string &name) const {
|
AtomicType::GetCDeclaration(const std::string &name) const {
|
||||||
std::string ret;
|
std::string ret;
|
||||||
if (variability != Variability::Uniform &&
|
if (variability != Variability::Uniform &&
|
||||||
variability != Variability::SOA) {
|
variability != Variability::SOA) {
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -583,7 +583,7 @@ AtomicType::GetDIType(llvm::DIDescriptor scope) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// EnumType
|
// EnumType
|
||||||
|
|
||||||
EnumType::EnumType(SourcePos p)
|
EnumType::EnumType(SourcePos p)
|
||||||
: Type(ENUM_TYPE), pos(p) {
|
: Type(ENUM_TYPE), pos(p) {
|
||||||
// name = "/* (anonymous) */";
|
// name = "/* (anonymous) */";
|
||||||
isConst = false;
|
isConst = false;
|
||||||
@@ -591,7 +591,7 @@ EnumType::EnumType(SourcePos p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EnumType::EnumType(const char *n, SourcePos p)
|
EnumType::EnumType(const char *n, SourcePos p)
|
||||||
: Type(ENUM_TYPE), pos(p), name(n) {
|
: Type(ENUM_TYPE), pos(p), name(n) {
|
||||||
isConst = false;
|
isConst = false;
|
||||||
variability = Variability(Variability::Unbound);
|
variability = Variability(Variability::Unbound);
|
||||||
@@ -604,31 +604,31 @@ EnumType::GetVariability() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EnumType::IsBoolType() const {
|
EnumType::IsBoolType() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EnumType::IsFloatType() const {
|
EnumType::IsFloatType() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EnumType::IsIntType() const {
|
EnumType::IsIntType() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EnumType::IsUnsignedType() const {
|
EnumType::IsUnsignedType() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EnumType::IsConstType() const {
|
EnumType::IsConstType() const {
|
||||||
return isConst;
|
return isConst;
|
||||||
}
|
}
|
||||||
@@ -724,7 +724,7 @@ EnumType::GetAsNonConstType() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
EnumType::GetString() const {
|
EnumType::GetString() const {
|
||||||
std::string ret;
|
std::string ret;
|
||||||
if (isConst) ret += "const ";
|
if (isConst) ret += "const ";
|
||||||
@@ -737,7 +737,7 @@ EnumType::GetString() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
EnumType::Mangle() const {
|
EnumType::Mangle() const {
|
||||||
Assert(variability != Variability::Unbound);
|
Assert(variability != Variability::Unbound);
|
||||||
|
|
||||||
@@ -749,7 +749,7 @@ EnumType::Mangle() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
EnumType::GetCDeclaration(const std::string &varName) const {
|
EnumType::GetCDeclaration(const std::string &varName) const {
|
||||||
if (variability != Variability::Uniform &&
|
if (variability != Variability::Uniform &&
|
||||||
variability != Variability::SOA) {
|
variability != Variability::SOA) {
|
||||||
@@ -798,7 +798,7 @@ EnumType::LLVMType(llvm::LLVMContext *ctx) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
llvm::DIType
|
llvm::DIType
|
||||||
EnumType::GetDIType(llvm::DIDescriptor scope) const {
|
EnumType::GetDIType(llvm::DIDescriptor scope) const {
|
||||||
std::vector<llvm::Value *> enumeratorDescriptors;
|
std::vector<llvm::Value *> enumeratorDescriptors;
|
||||||
for (unsigned int i = 0; i < enumerators.size(); ++i) {
|
for (unsigned int i = 0; i < enumerators.size(); ++i) {
|
||||||
@@ -807,11 +807,11 @@ EnumType::GetDIType(llvm::DIDescriptor scope) const {
|
|||||||
int count = enumerators[i]->constValue->AsUInt32(&enumeratorValue);
|
int count = enumerators[i]->constValue->AsUInt32(&enumeratorValue);
|
||||||
Assert(count == 1);
|
Assert(count == 1);
|
||||||
|
|
||||||
llvm::Value *descriptor =
|
llvm::Value *descriptor =
|
||||||
m->diBuilder->createEnumerator(enumerators[i]->name, enumeratorValue);
|
m->diBuilder->createEnumerator(enumerators[i]->name, enumeratorValue);
|
||||||
enumeratorDescriptors.push_back(descriptor);
|
enumeratorDescriptors.push_back(descriptor);
|
||||||
}
|
}
|
||||||
llvm::DIArray elementArray =
|
llvm::DIArray elementArray =
|
||||||
m->diBuilder->getOrCreateArray(enumeratorDescriptors);
|
m->diBuilder->getOrCreateArray(enumeratorDescriptors);
|
||||||
|
|
||||||
llvm::DIFile diFile = pos.GetDIFile();
|
llvm::DIFile diFile = pos.GetDIFile();
|
||||||
@@ -867,11 +867,11 @@ EnumType::GetEnumerator(int i) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// PointerType
|
// PointerType
|
||||||
|
|
||||||
PointerType *PointerType::Void =
|
PointerType *PointerType::Void =
|
||||||
new PointerType(AtomicType::Void, Variability(Variability::Uniform), false);
|
new PointerType(AtomicType::Void, Variability(Variability::Uniform), false);
|
||||||
|
|
||||||
|
|
||||||
PointerType::PointerType(const Type *t, Variability v, bool ic, bool is,
|
PointerType::PointerType(const Type *t, Variability v, bool ic, bool is,
|
||||||
bool fr)
|
bool fr)
|
||||||
: Type(POINTER_TYPE), variability(v), isConst(ic), isSlice(is), isFrozen(fr) {
|
: Type(POINTER_TYPE), variability(v), isConst(ic), isSlice(is), isFrozen(fr) {
|
||||||
baseType = t;
|
baseType = t;
|
||||||
@@ -1013,7 +1013,7 @@ PointerType::ResolveUnboundVariability(Variability v) const {
|
|||||||
Assert(v != Variability::Unbound);
|
Assert(v != Variability::Unbound);
|
||||||
Variability ptrVariability = (variability == Variability::Unbound) ? v :
|
Variability ptrVariability = (variability == Variability::Unbound) ? v :
|
||||||
variability;
|
variability;
|
||||||
const Type *resolvedBaseType =
|
const Type *resolvedBaseType =
|
||||||
baseType->ResolveUnboundVariability(Variability::Uniform);
|
baseType->ResolveUnboundVariability(Variability::Uniform);
|
||||||
return new PointerType(resolvedBaseType, ptrVariability, isConst, isSlice,
|
return new PointerType(resolvedBaseType, ptrVariability, isConst, isSlice,
|
||||||
isFrozen);
|
isFrozen);
|
||||||
@@ -1038,7 +1038,7 @@ PointerType::GetAsNonConstType() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
PointerType::GetString() const {
|
PointerType::GetString() const {
|
||||||
if (baseType == NULL) {
|
if (baseType == NULL) {
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
@@ -1114,7 +1114,7 @@ PointerType::LLVMType(llvm::LLVMContext *ctx) const {
|
|||||||
if (isSlice) {
|
if (isSlice) {
|
||||||
llvm::Type *types[2];
|
llvm::Type *types[2];
|
||||||
types[0] = GetAsNonSlice()->LLVMType(ctx);
|
types[0] = GetAsNonSlice()->LLVMType(ctx);
|
||||||
|
|
||||||
switch (variability.type) {
|
switch (variability.type) {
|
||||||
case Variability::Uniform:
|
case Variability::Uniform:
|
||||||
types[1] = LLVMTypes::Int32Type;
|
types[1] = LLVMTypes::Int32Type;
|
||||||
@@ -1140,7 +1140,7 @@ PointerType::LLVMType(llvm::LLVMContext *ctx) const {
|
|||||||
case Variability::Uniform: {
|
case Variability::Uniform: {
|
||||||
llvm::Type *ptype = NULL;
|
llvm::Type *ptype = NULL;
|
||||||
const FunctionType *ftype = CastType<FunctionType>(baseType);
|
const FunctionType *ftype = CastType<FunctionType>(baseType);
|
||||||
if (ftype != NULL)
|
if (ftype != NULL)
|
||||||
ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx), 0);
|
ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx), 0);
|
||||||
else {
|
else {
|
||||||
if (baseType == AtomicType::Void)
|
if (baseType == AtomicType::Void)
|
||||||
@@ -1177,11 +1177,11 @@ PointerType::GetDIType(llvm::DIDescriptor scope) const {
|
|||||||
int ptrAlignBits = bitsSize;
|
int ptrAlignBits = bitsSize;
|
||||||
switch (variability.type) {
|
switch (variability.type) {
|
||||||
case Variability::Uniform:
|
case Variability::Uniform:
|
||||||
return m->diBuilder->createPointerType(diTargetType, bitsSize,
|
return m->diBuilder->createPointerType(diTargetType, bitsSize,
|
||||||
ptrAlignBits);
|
ptrAlignBits);
|
||||||
case Variability::Varying: {
|
case Variability::Varying: {
|
||||||
// emit them as an array of pointers
|
// emit them as an array of pointers
|
||||||
llvm::DIType eltType = m->diBuilder->createPointerType(diTargetType,
|
llvm::DIType eltType = m->diBuilder->createPointerType(diTargetType,
|
||||||
bitsSize, ptrAlignBits);
|
bitsSize, ptrAlignBits);
|
||||||
return lCreateDIArray(eltType, g->target.vectorWidth);
|
return lCreateDIArray(eltType, g->target.vectorWidth);
|
||||||
}
|
}
|
||||||
@@ -1207,7 +1207,7 @@ const Type *SequentialType::GetElementType(int index) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// ArrayType
|
// ArrayType
|
||||||
|
|
||||||
ArrayType::ArrayType(const Type *c, int a)
|
ArrayType::ArrayType(const Type *c, int a)
|
||||||
: SequentialType(ARRAY_TYPE), child(c), numElements(a) {
|
: SequentialType(ARRAY_TYPE), child(c), numElements(a) {
|
||||||
// 0 -> unsized array.
|
// 0 -> unsized array.
|
||||||
Assert(numElements >= 0);
|
Assert(numElements >= 0);
|
||||||
@@ -1239,25 +1239,25 @@ ArrayType::GetVariability() const {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
ArrayType::IsFloatType() const {
|
ArrayType::IsFloatType() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ArrayType::IsIntType() const {
|
ArrayType::IsIntType() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ArrayType::IsUnsignedType() const {
|
ArrayType::IsUnsignedType() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ArrayType::IsBoolType() const {
|
ArrayType::IsBoolType() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1519,7 +1519,7 @@ ArrayType::SizeUnsizedArrays(const Type *type, Expr *initExpr) {
|
|||||||
|
|
||||||
ExprList *el = dynamic_cast<ExprList *>(exprList->exprs[i]);
|
ExprList *el = dynamic_cast<ExprList *>(exprList->exprs[i]);
|
||||||
if (el == NULL || el->exprs.size() != nextSize) {
|
if (el == NULL || el->exprs.size() != nextSize) {
|
||||||
Error(Union(exprList->exprs[0]->pos, exprList->exprs[i]->pos),
|
Error(Union(exprList->exprs[0]->pos, exprList->exprs[i]->pos),
|
||||||
"Inconsistent initializer expression list lengths "
|
"Inconsistent initializer expression list lengths "
|
||||||
"make it impossible to size unsized array dimensions.");
|
"make it impossible to size unsized array dimensions.");
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1537,7 +1537,7 @@ ArrayType::SizeUnsizedArrays(const Type *type, Expr *initExpr) {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// VectorType
|
// VectorType
|
||||||
|
|
||||||
VectorType::VectorType(const AtomicType *b, int a)
|
VectorType::VectorType(const AtomicType *b, int a)
|
||||||
: SequentialType(VECTOR_TYPE), base(b), numElements(a) {
|
: SequentialType(VECTOR_TYPE), base(b), numElements(a) {
|
||||||
Assert(numElements > 0);
|
Assert(numElements > 0);
|
||||||
Assert(base != NULL);
|
Assert(base != NULL);
|
||||||
@@ -1546,37 +1546,37 @@ VectorType::VectorType(const AtomicType *b, int a)
|
|||||||
|
|
||||||
Variability
|
Variability
|
||||||
VectorType::GetVariability() const {
|
VectorType::GetVariability() const {
|
||||||
return base->GetVariability();
|
return base->GetVariability();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VectorType::IsFloatType() const {
|
VectorType::IsFloatType() const {
|
||||||
return base->IsFloatType();
|
return base->IsFloatType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VectorType::IsIntType() const {
|
VectorType::IsIntType() const {
|
||||||
return base->IsIntType();
|
return base->IsIntType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VectorType::IsUnsignedType() const {
|
VectorType::IsUnsignedType() const {
|
||||||
return base->IsUnsignedType();
|
return base->IsUnsignedType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VectorType::IsBoolType() const {
|
VectorType::IsBoolType() const {
|
||||||
return base->IsBoolType();
|
return base->IsBoolType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VectorType::IsConstType() const {
|
VectorType::IsConstType() const {
|
||||||
return base->IsConstType();
|
return base->IsConstType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1796,22 +1796,22 @@ lMangleStructName(const std::string &name, Variability variability) {
|
|||||||
default:
|
default:
|
||||||
FATAL("Unexpected variability in lMangleStructName()");
|
FATAL("Unexpected variability in lMangleStructName()");
|
||||||
}
|
}
|
||||||
|
|
||||||
// And stuff the name at the end....
|
// And stuff the name at the end....
|
||||||
n += name;
|
n += name;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
StructType::StructType(const std::string &n, const llvm::SmallVector<const Type *, 8> &elts,
|
StructType::StructType(const std::string &n, const llvm::SmallVector<const Type *, 8> &elts,
|
||||||
const llvm::SmallVector<std::string, 8> &en,
|
const llvm::SmallVector<std::string, 8> &en,
|
||||||
const llvm::SmallVector<SourcePos, 8> &ep,
|
const llvm::SmallVector<SourcePos, 8> &ep,
|
||||||
bool ic, Variability v, SourcePos p)
|
bool ic, Variability v, SourcePos p)
|
||||||
: CollectionType(STRUCT_TYPE), name(n), elementTypes(elts), elementNames(en),
|
: CollectionType(STRUCT_TYPE), name(n), elementTypes(elts), elementNames(en),
|
||||||
elementPositions(ep), variability(v), isConst(ic), pos(p) {
|
elementPositions(ep), variability(v), isConst(ic), pos(p) {
|
||||||
oppositeConstStructType = NULL;
|
oppositeConstStructType = NULL;
|
||||||
finalElementTypes.resize(elts.size(), NULL);
|
finalElementTypes.resize(elts.size(), NULL);
|
||||||
|
|
||||||
if (variability != Variability::Unbound) {
|
if (variability != Variability::Unbound) {
|
||||||
// For structs with non-unbound variability, we'll create the
|
// For structs with non-unbound variability, we'll create the
|
||||||
// correspoing LLVM struct type now, if one hasn't been made
|
// correspoing LLVM struct type now, if one hasn't been made
|
||||||
@@ -1875,37 +1875,37 @@ StructType::StructType(const std::string &n, const llvm::SmallVector<const Type
|
|||||||
|
|
||||||
Variability
|
Variability
|
||||||
StructType::GetVariability() const {
|
StructType::GetVariability() const {
|
||||||
return variability;
|
return variability;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StructType::IsBoolType() const {
|
StructType::IsBoolType() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StructType::IsFloatType() const {
|
StructType::IsFloatType() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StructType::IsIntType() const {
|
StructType::IsIntType() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StructType::IsUnsignedType() const {
|
StructType::IsUnsignedType() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StructType::IsConstType() const {
|
StructType::IsConstType() const {
|
||||||
return isConst;
|
return isConst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1917,7 +1917,7 @@ StructType::GetBaseType() const {
|
|||||||
|
|
||||||
const StructType *
|
const StructType *
|
||||||
StructType::GetAsVaryingType() const {
|
StructType::GetAsVaryingType() const {
|
||||||
if (IsVaryingType())
|
if (IsVaryingType())
|
||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new StructType(name, elementTypes, elementNames, elementPositions,
|
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||||
@@ -1927,7 +1927,7 @@ StructType::GetAsVaryingType() const {
|
|||||||
|
|
||||||
const StructType *
|
const StructType *
|
||||||
StructType::GetAsUniformType() const {
|
StructType::GetAsUniformType() const {
|
||||||
if (IsUniformType())
|
if (IsUniformType())
|
||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new StructType(name, elementTypes, elementNames, elementPositions,
|
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||||
@@ -1937,7 +1937,7 @@ StructType::GetAsUniformType() const {
|
|||||||
|
|
||||||
const StructType *
|
const StructType *
|
||||||
StructType::GetAsUnboundVariabilityType() const {
|
StructType::GetAsUnboundVariabilityType() const {
|
||||||
if (HasUnboundVariability())
|
if (HasUnboundVariability())
|
||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new StructType(name, elementTypes, elementNames, elementPositions,
|
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||||
@@ -1981,7 +1981,7 @@ StructType::GetAsConstType() const {
|
|||||||
else if (oppositeConstStructType != NULL)
|
else if (oppositeConstStructType != NULL)
|
||||||
return oppositeConstStructType;
|
return oppositeConstStructType;
|
||||||
else {
|
else {
|
||||||
oppositeConstStructType =
|
oppositeConstStructType =
|
||||||
new StructType(name, elementTypes, elementNames, elementPositions,
|
new StructType(name, elementTypes, elementNames, elementPositions,
|
||||||
true, variability, pos);
|
true, variability, pos);
|
||||||
oppositeConstStructType->oppositeConstStructType = this;
|
oppositeConstStructType->oppositeConstStructType = this;
|
||||||
@@ -1997,7 +1997,7 @@ StructType::GetAsNonConstType() const {
|
|||||||
else if (oppositeConstStructType != NULL)
|
else if (oppositeConstStructType != NULL)
|
||||||
return oppositeConstStructType;
|
return oppositeConstStructType;
|
||||||
else {
|
else {
|
||||||
oppositeConstStructType =
|
oppositeConstStructType =
|
||||||
new StructType(name, elementTypes, elementNames, elementPositions,
|
new StructType(name, elementTypes, elementNames, elementPositions,
|
||||||
false, variability, pos);
|
false, variability, pos);
|
||||||
oppositeConstStructType->oppositeConstStructType = this;
|
oppositeConstStructType->oppositeConstStructType = this;
|
||||||
@@ -2115,9 +2115,9 @@ StructType::GetDIType(llvm::DIDescriptor scope) const {
|
|||||||
|
|
||||||
llvm::DIFile diFile = elementPositions[i].GetDIFile();
|
llvm::DIFile diFile = elementPositions[i].GetDIFile();
|
||||||
int line = elementPositions[i].first_line;
|
int line = elementPositions[i].first_line;
|
||||||
llvm::DIType fieldType =
|
llvm::DIType fieldType =
|
||||||
m->diBuilder->createMemberType(scope, elementNames[i], diFile,
|
m->diBuilder->createMemberType(scope, elementNames[i], diFile,
|
||||||
line, eltSize, eltAlign,
|
line, eltSize, eltAlign,
|
||||||
currentSize, 0, eltType);
|
currentSize, 0, eltType);
|
||||||
elementLLVMTypes.push_back(fieldType);
|
elementLLVMTypes.push_back(fieldType);
|
||||||
|
|
||||||
@@ -2201,7 +2201,7 @@ StructType::checkIfCanBeSOA(const StructType *st) {
|
|||||||
Error(st->elementPositions[i], "Unable to apply SOA conversion to "
|
Error(st->elementPositions[i], "Unable to apply SOA conversion to "
|
||||||
"struct due to \"%s\" member \"%s\" with bound \"%s\" "
|
"struct due to \"%s\" member \"%s\" with bound \"%s\" "
|
||||||
"variability.", eltType->GetString().c_str(),
|
"variability.", eltType->GetString().c_str(),
|
||||||
st->elementNames[i].c_str(),
|
st->elementNames[i].c_str(),
|
||||||
eltType->IsUniformType() ? "uniform" : "varying");
|
eltType->IsUniformType() ? "uniform" : "varying");
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
@@ -2219,9 +2219,9 @@ StructType::checkIfCanBeSOA(const StructType *st) {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// UndefinedStructType
|
// UndefinedStructType
|
||||||
|
|
||||||
UndefinedStructType::UndefinedStructType(const std::string &n,
|
UndefinedStructType::UndefinedStructType(const std::string &n,
|
||||||
const Variability var, bool ic,
|
const Variability var, bool ic,
|
||||||
SourcePos p)
|
SourcePos p)
|
||||||
: Type(UNDEFINED_STRUCT_TYPE), name(n), variability(var), isConst(ic), pos(p) {
|
: Type(UNDEFINED_STRUCT_TYPE), name(n), variability(var), isConst(ic), pos(p) {
|
||||||
Assert(name != "");
|
Assert(name != "");
|
||||||
if (variability != Variability::Unbound) {
|
if (variability != Variability::Unbound) {
|
||||||
@@ -2392,7 +2392,7 @@ UndefinedStructType::GetDIType(llvm::DIDescriptor scope) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// ReferenceType
|
// ReferenceType
|
||||||
|
|
||||||
ReferenceType::ReferenceType(const Type *t)
|
ReferenceType::ReferenceType(const Type *t)
|
||||||
: Type(REFERENCE_TYPE), targetType(t) {
|
: Type(REFERENCE_TYPE), targetType(t) {
|
||||||
asOtherConstType = NULL;
|
asOtherConstType = NULL;
|
||||||
}
|
}
|
||||||
@@ -2404,7 +2404,7 @@ ReferenceType::GetVariability() const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return Variability(Variability::Unbound);
|
return Variability(Variability::Unbound);
|
||||||
}
|
}
|
||||||
return targetType->GetVariability();
|
return targetType->GetVariability();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2414,7 +2414,7 @@ ReferenceType::IsBoolType() const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return targetType->IsBoolType();
|
return targetType->IsBoolType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2424,7 +2424,7 @@ ReferenceType::IsFloatType() const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return targetType->IsFloatType();
|
return targetType->IsFloatType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2434,7 +2434,7 @@ ReferenceType::IsIntType() const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return targetType->IsIntType();
|
return targetType->IsIntType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2444,7 +2444,7 @@ ReferenceType::IsUnsignedType() const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return targetType->IsUnsignedType();
|
return targetType->IsUnsignedType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2480,7 +2480,7 @@ ReferenceType::GetAsVaryingType() const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (IsVaryingType())
|
if (IsVaryingType())
|
||||||
return this;
|
return this;
|
||||||
return new ReferenceType(targetType->GetAsVaryingType());
|
return new ReferenceType(targetType->GetAsVaryingType());
|
||||||
}
|
}
|
||||||
@@ -2492,7 +2492,7 @@ ReferenceType::GetAsUniformType() const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (IsUniformType())
|
if (IsUniformType())
|
||||||
return this;
|
return this;
|
||||||
return new ReferenceType(targetType->GetAsUniformType());
|
return new ReferenceType(targetType->GetAsUniformType());
|
||||||
}
|
}
|
||||||
@@ -2504,7 +2504,7 @@ ReferenceType::GetAsUnboundVariabilityType() const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (HasUnboundVariability())
|
if (HasUnboundVariability())
|
||||||
return this;
|
return this;
|
||||||
return new ReferenceType(targetType->GetAsUnboundVariabilityType());
|
return new ReferenceType(targetType->GetAsUnboundVariabilityType());
|
||||||
}
|
}
|
||||||
@@ -2525,7 +2525,7 @@ ReferenceType::ResolveUnboundVariability(Variability v) const {
|
|||||||
}
|
}
|
||||||
return new ReferenceType(targetType->ResolveUnboundVariability(v));
|
return new ReferenceType(targetType->ResolveUnboundVariability(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ReferenceType *
|
const ReferenceType *
|
||||||
ReferenceType::GetAsConstType() const {
|
ReferenceType::GetAsConstType() const {
|
||||||
@@ -2599,7 +2599,7 @@ ReferenceType::GetCDeclaration(const std::string &name) const {
|
|||||||
if (at->GetElementCount() == 0) {
|
if (at->GetElementCount() == 0) {
|
||||||
// emit unsized arrays as pointers to the base type..
|
// emit unsized arrays as pointers to the base type..
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret += at->GetElementType()->GetAsNonConstType()->GetCDeclaration("") +
|
ret += at->GetElementType()->GetAsNonConstType()->GetCDeclaration("") +
|
||||||
std::string(" *");
|
std::string(" *");
|
||||||
if (lShouldPrintName(name))
|
if (lShouldPrintName(name))
|
||||||
ret += name;
|
ret += name;
|
||||||
@@ -2657,11 +2657,11 @@ ReferenceType::GetDIType(llvm::DIDescriptor scope) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// FunctionType
|
// FunctionType
|
||||||
|
|
||||||
FunctionType::FunctionType(const Type *r,
|
FunctionType::FunctionType(const Type *r,
|
||||||
const llvm::SmallVector<const Type *, 8> &a,
|
const llvm::SmallVector<const Type *, 8> &a,
|
||||||
SourcePos p)
|
SourcePos p)
|
||||||
: Type(FUNCTION_TYPE), isTask(false), isExported(false), isExternC(false),
|
: Type(FUNCTION_TYPE), isTask(false), isExported(false), isExternC(false),
|
||||||
isUnmasked(false), returnType(r), paramTypes(a),
|
isUnmasked(false), returnType(r), paramTypes(a),
|
||||||
paramNames(llvm::SmallVector<std::string, 8>(a.size(), "")),
|
paramNames(llvm::SmallVector<std::string, 8>(a.size(), "")),
|
||||||
paramDefaults(llvm::SmallVector<Expr *, 8>(a.size(), NULL)),
|
paramDefaults(llvm::SmallVector<Expr *, 8>(a.size(), NULL)),
|
||||||
paramPositions(llvm::SmallVector<SourcePos, 8>(a.size(), p)) {
|
paramPositions(llvm::SmallVector<SourcePos, 8>(a.size(), p)) {
|
||||||
@@ -2672,15 +2672,15 @@ FunctionType::FunctionType(const Type *r,
|
|||||||
|
|
||||||
|
|
||||||
FunctionType::FunctionType(const Type *r,
|
FunctionType::FunctionType(const Type *r,
|
||||||
const llvm::SmallVector<const Type *, 8> &a,
|
const llvm::SmallVector<const Type *, 8> &a,
|
||||||
const llvm::SmallVector<std::string, 8> &an,
|
const llvm::SmallVector<std::string, 8> &an,
|
||||||
const llvm::SmallVector<Expr *, 8> &ad,
|
const llvm::SmallVector<Expr *, 8> &ad,
|
||||||
const llvm::SmallVector<SourcePos, 8> &ap,
|
const llvm::SmallVector<SourcePos, 8> &ap,
|
||||||
bool it, bool is, bool ec, bool ium)
|
bool it, bool is, bool ec, bool ium)
|
||||||
: Type(FUNCTION_TYPE), isTask(it), isExported(is), isExternC(ec),
|
: Type(FUNCTION_TYPE), isTask(it), isExported(is), isExternC(ec),
|
||||||
isUnmasked(ium), returnType(r), paramTypes(a), paramNames(an),
|
isUnmasked(ium), returnType(r), paramTypes(a), paramNames(an),
|
||||||
paramDefaults(ad), paramPositions(ap) {
|
paramDefaults(ad), paramPositions(ap) {
|
||||||
Assert(paramTypes.size() == paramNames.size() &&
|
Assert(paramTypes.size() == paramNames.size() &&
|
||||||
paramNames.size() == paramDefaults.size() &&
|
paramNames.size() == paramDefaults.size() &&
|
||||||
paramDefaults.size() == paramPositions.size());
|
paramDefaults.size() == paramPositions.size());
|
||||||
Assert(returnType != NULL);
|
Assert(returnType != NULL);
|
||||||
@@ -2847,7 +2847,7 @@ FunctionType::GetCDeclaration(const std::string &fname) const {
|
|||||||
// to print out for multidimensional arrays (i.e. "float foo[][4] "
|
// to print out for multidimensional arrays (i.e. "float foo[][4] "
|
||||||
// versus "float (foo *)[4]").
|
// versus "float (foo *)[4]").
|
||||||
const PointerType *pt = CastType<PointerType>(type);
|
const PointerType *pt = CastType<PointerType>(type);
|
||||||
if (pt != NULL &&
|
if (pt != NULL &&
|
||||||
CastType<ArrayType>(pt->GetBaseType()) != NULL) {
|
CastType<ArrayType>(pt->GetBaseType()) != NULL) {
|
||||||
type = new ArrayType(pt->GetBaseType(), 0);
|
type = new ArrayType(pt->GetBaseType(), 0);
|
||||||
}
|
}
|
||||||
@@ -2883,10 +2883,10 @@ FunctionType::GetDIType(llvm::DIDescriptor scope) const {
|
|||||||
retArgTypes.push_back(t->GetDIType(scope));
|
retArgTypes.push_back(t->GetDIType(scope));
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::DIArray retArgTypesArray =
|
llvm::DIArray retArgTypesArray =
|
||||||
m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(retArgTypes));
|
m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(retArgTypes));
|
||||||
llvm::DIType diType =
|
llvm::DIType diType =
|
||||||
// FIXME: DIFile
|
// FIXME: DIFile
|
||||||
m->diBuilder->createSubroutineType(llvm::DIFile(), retArgTypesArray);
|
m->diBuilder->createSubroutineType(llvm::DIFile(), retArgTypesArray);
|
||||||
return diType;
|
return diType;
|
||||||
}
|
}
|
||||||
@@ -2906,7 +2906,7 @@ FunctionType::GetReturnTypeString() const {
|
|||||||
ret += "extern \"C\" ";
|
ret += "extern \"C\" ";
|
||||||
if (isUnmasked)
|
if (isUnmasked)
|
||||||
ret += "unmasked ";
|
ret += "unmasked ";
|
||||||
if (isSafe)
|
if (isSafe)
|
||||||
ret += "/*safe*/ ";
|
ret += "/*safe*/ ";
|
||||||
if (costOverride > 0) {
|
if (costOverride > 0) {
|
||||||
char buf[32];
|
char buf[32];
|
||||||
@@ -2920,7 +2920,7 @@ FunctionType::GetReturnTypeString() const {
|
|||||||
|
|
||||||
llvm::FunctionType *
|
llvm::FunctionType *
|
||||||
FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
|
FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
|
||||||
if (isTask == true)
|
if (isTask == true)
|
||||||
Assert(removeMask == false);
|
Assert(removeMask == false);
|
||||||
|
|
||||||
// Get the LLVM Type *s for the function arguments
|
// Get the LLVM Type *s for the function arguments
|
||||||
@@ -2959,7 +2959,7 @@ FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
|
|||||||
callTypes.push_back(LLVMTypes::Int32Type); // taskCount
|
callTypes.push_back(LLVMTypes::Int32Type); // taskCount
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// Otherwise we already have the types of the arguments
|
// Otherwise we already have the types of the arguments
|
||||||
callTypes = llvmArgTypes;
|
callTypes = llvmArgTypes;
|
||||||
|
|
||||||
if (returnType == NULL) {
|
if (returnType == NULL) {
|
||||||
@@ -2976,30 +2976,30 @@ FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
|
|||||||
|
|
||||||
|
|
||||||
const Type *
|
const Type *
|
||||||
FunctionType::GetParameterType(int i) const {
|
FunctionType::GetParameterType(int i) const {
|
||||||
Assert(i < (int)paramTypes.size());
|
Assert(i < (int)paramTypes.size());
|
||||||
return paramTypes[i];
|
return paramTypes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Expr *
|
Expr *
|
||||||
FunctionType::GetParameterDefault(int i) const {
|
FunctionType::GetParameterDefault(int i) const {
|
||||||
Assert(i < (int)paramDefaults.size());
|
Assert(i < (int)paramDefaults.size());
|
||||||
return paramDefaults[i];
|
return paramDefaults[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const SourcePos &
|
const SourcePos &
|
||||||
FunctionType::GetParameterSourcePos(int i) const {
|
FunctionType::GetParameterSourcePos(int i) const {
|
||||||
Assert(i < (int)paramPositions.size());
|
Assert(i < (int)paramPositions.size());
|
||||||
return paramPositions[i];
|
return paramPositions[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::string &
|
const std::string &
|
||||||
FunctionType::GetParameterName(int i) const {
|
FunctionType::GetParameterName(int i) const {
|
||||||
Assert(i < (int)paramNames.size());
|
Assert(i < (int)paramNames.size());
|
||||||
return paramNames[i];
|
return paramNames[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3030,7 +3030,7 @@ lVectorConvert(const Type *type, SourcePos pos, const char *reason, int vecSize)
|
|||||||
if (vt) {
|
if (vt) {
|
||||||
if (vt->GetElementCount() != vecSize) {
|
if (vt->GetElementCount() != vecSize) {
|
||||||
Error(pos, "Implicit conversion between from vector type "
|
Error(pos, "Implicit conversion between from vector type "
|
||||||
"\"%s\" to vector type of length %d for %s is not possible.",
|
"\"%s\" to vector type of length %d for %s is not possible.",
|
||||||
type->GetString().c_str(), vecSize, reason);
|
type->GetString().c_str(), vecSize, reason);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -3049,7 +3049,7 @@ lVectorConvert(const Type *type, SourcePos pos, const char *reason, int vecSize)
|
|||||||
|
|
||||||
|
|
||||||
const Type *
|
const Type *
|
||||||
Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char *reason,
|
Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char *reason,
|
||||||
bool forceVarying, int vecSize) {
|
bool forceVarying, int vecSize) {
|
||||||
Assert(reason != NULL);
|
Assert(reason != NULL);
|
||||||
|
|
||||||
@@ -3080,9 +3080,9 @@ Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Are they both the same type? If so, we're done, QED.
|
// Are they both the same type? If so, we're done, QED.
|
||||||
if (Type::Equal(t0, t1))
|
if (Type::Equal(t0, t1))
|
||||||
return t0;
|
return t0;
|
||||||
|
|
||||||
// If they're function types, it's hopeless if they didn't match in the
|
// If they're function types, it's hopeless if they didn't match in the
|
||||||
// Type::Equal() call above. Fail here so that we don't get into
|
// Type::Equal() call above. Fail here so that we don't get into
|
||||||
// trouble calling GetAsConstType()...
|
// trouble calling GetAsConstType()...
|
||||||
@@ -3125,7 +3125,7 @@ Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char
|
|||||||
}
|
}
|
||||||
const Type *t = MoreGeneralType(vt0->GetElementType(), vt1->GetElementType(),
|
const Type *t = MoreGeneralType(vt0->GetElementType(), vt1->GetElementType(),
|
||||||
pos, reason, forceVarying);
|
pos, reason, forceVarying);
|
||||||
if (!t)
|
if (!t)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// The 'more general' version of the two vector element types must
|
// The 'more general' version of the two vector element types must
|
||||||
@@ -3140,9 +3140,9 @@ Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char
|
|||||||
// promote the other one to a vector type. This will fail and
|
// promote the other one to a vector type. This will fail and
|
||||||
// return NULL if t1 is e.g. an array type and it's illegal to have
|
// return NULL if t1 is e.g. an array type and it's illegal to have
|
||||||
// a vector of it..
|
// a vector of it..
|
||||||
const Type *t = MoreGeneralType(vt0->GetElementType(), t1, pos,
|
const Type *t = MoreGeneralType(vt0->GetElementType(), t1, pos,
|
||||||
reason, forceVarying);
|
reason, forceVarying);
|
||||||
if (!t)
|
if (!t)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const AtomicType *at = CastType<AtomicType>(t);
|
const AtomicType *at = CastType<AtomicType>(t);
|
||||||
@@ -3152,9 +3152,9 @@ Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char
|
|||||||
else if (vt1) {
|
else if (vt1) {
|
||||||
// As in the above case, see if we can promote t0 to make a vector
|
// As in the above case, see if we can promote t0 to make a vector
|
||||||
// that matches vt1.
|
// that matches vt1.
|
||||||
const Type *t = MoreGeneralType(t0, vt1->GetElementType(), pos,
|
const Type *t = MoreGeneralType(t0, vt1->GetElementType(), pos,
|
||||||
reason, forceVarying);
|
reason, forceVarying);
|
||||||
if (!t)
|
if (!t)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const AtomicType *at = CastType<AtomicType>(t);
|
const AtomicType *at = CastType<AtomicType>(t);
|
||||||
@@ -3234,7 +3234,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
|
|||||||
const AtomicType *ata = CastType<AtomicType>(a);
|
const AtomicType *ata = CastType<AtomicType>(a);
|
||||||
const AtomicType *atb = CastType<AtomicType>(b);
|
const AtomicType *atb = CastType<AtomicType>(b);
|
||||||
if (ata != NULL && atb != NULL) {
|
if (ata != NULL && atb != NULL) {
|
||||||
return ((ata->basicType == atb->basicType) &&
|
return ((ata->basicType == atb->basicType) &&
|
||||||
(ata->GetVariability() == atb->GetVariability()));
|
(ata->GetVariability() == atb->GetVariability()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3251,14 +3251,14 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
|
|||||||
const ArrayType *arta = CastType<ArrayType>(a);
|
const ArrayType *arta = CastType<ArrayType>(a);
|
||||||
const ArrayType *artb = CastType<ArrayType>(b);
|
const ArrayType *artb = CastType<ArrayType>(b);
|
||||||
if (arta != NULL && artb != NULL)
|
if (arta != NULL && artb != NULL)
|
||||||
return (arta->GetElementCount() == artb->GetElementCount() &&
|
return (arta->GetElementCount() == artb->GetElementCount() &&
|
||||||
lCheckTypeEquality(arta->GetElementType(), artb->GetElementType(),
|
lCheckTypeEquality(arta->GetElementType(), artb->GetElementType(),
|
||||||
ignoreConst));
|
ignoreConst));
|
||||||
|
|
||||||
const VectorType *vta = CastType<VectorType>(a);
|
const VectorType *vta = CastType<VectorType>(a);
|
||||||
const VectorType *vtb = CastType<VectorType>(b);
|
const VectorType *vtb = CastType<VectorType>(b);
|
||||||
if (vta != NULL && vtb != NULL)
|
if (vta != NULL && vtb != NULL)
|
||||||
return (vta->GetElementCount() == vtb->GetElementCount() &&
|
return (vta->GetElementCount() == vtb->GetElementCount() &&
|
||||||
lCheckTypeEquality(vta->GetElementType(), vtb->GetElementType(),
|
lCheckTypeEquality(vta->GetElementType(), vtb->GetElementType(),
|
||||||
ignoreConst));
|
ignoreConst));
|
||||||
|
|
||||||
@@ -3272,7 +3272,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
|
|||||||
if (a->GetVariability() != b->GetVariability())
|
if (a->GetVariability() != b->GetVariability())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const std::string &namea = sta ? sta->GetStructName() :
|
const std::string &namea = sta ? sta->GetStructName() :
|
||||||
usta->GetStructName();
|
usta->GetStructName();
|
||||||
const std::string &nameb = stb ? stb->GetStructName() :
|
const std::string &nameb = stb ? stb->GetStructName() :
|
||||||
ustb->GetStructName();
|
ustb->GetStructName();
|
||||||
@@ -3285,7 +3285,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
|
|||||||
return (pta->IsUniformType() == ptb->IsUniformType() &&
|
return (pta->IsUniformType() == ptb->IsUniformType() &&
|
||||||
pta->IsSlice() == ptb->IsSlice() &&
|
pta->IsSlice() == ptb->IsSlice() &&
|
||||||
pta->IsFrozenSlice() == ptb->IsFrozenSlice() &&
|
pta->IsFrozenSlice() == ptb->IsFrozenSlice() &&
|
||||||
lCheckTypeEquality(pta->GetBaseType(), ptb->GetBaseType(),
|
lCheckTypeEquality(pta->GetBaseType(), ptb->GetBaseType(),
|
||||||
ignoreConst));
|
ignoreConst));
|
||||||
|
|
||||||
const ReferenceType *rta = CastType<ReferenceType>(a);
|
const ReferenceType *rta = CastType<ReferenceType>(a);
|
||||||
@@ -3299,7 +3299,7 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
|
|||||||
if (fta != NULL && ftb != NULL) {
|
if (fta != NULL && ftb != NULL) {
|
||||||
// Both the return types and all of the argument types must match
|
// Both the return types and all of the argument types must match
|
||||||
// for function types to match
|
// for function types to match
|
||||||
if (!lCheckTypeEquality(fta->GetReturnType(), ftb->GetReturnType(),
|
if (!lCheckTypeEquality(fta->GetReturnType(), ftb->GetReturnType(),
|
||||||
ignoreConst))
|
ignoreConst))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
70
type.h
70
type.h
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file type.h
|
/** @file type.h
|
||||||
@@ -53,17 +53,17 @@ class ConstExpr;
|
|||||||
class StructType;
|
class StructType;
|
||||||
|
|
||||||
/** Types may have uniform, varying, SOA, or unbound variability; this
|
/** Types may have uniform, varying, SOA, or unbound variability; this
|
||||||
struct is used by Type implementations to record their variability.
|
struct is used by Type implementations to record their variability.
|
||||||
*/
|
*/
|
||||||
struct Variability {
|
struct Variability {
|
||||||
enum VarType { Unbound, Uniform, Varying, SOA };
|
enum VarType { Unbound, Uniform, Varying, SOA };
|
||||||
|
|
||||||
Variability(VarType t = Unbound, int w = 0) : type(t), soaWidth(w) { }
|
Variability(VarType t = Unbound, int w = 0) : type(t), soaWidth(w) { }
|
||||||
|
|
||||||
bool operator==(const Variability &v) const {
|
bool operator==(const Variability &v) const {
|
||||||
return v.type == type && v.soaWidth == soaWidth;
|
return v.type == type && v.soaWidth == soaWidth;
|
||||||
}
|
}
|
||||||
bool operator!=(const Variability &v) const {
|
bool operator!=(const Variability &v) const {
|
||||||
return v.type != type || v.soaWidth != soaWidth;
|
return v.type != type || v.soaWidth != soaWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ struct Variability {
|
|||||||
|
|
||||||
std::string GetString() const;
|
std::string GetString() const;
|
||||||
std::string MangleString() const;
|
std::string MangleString() const;
|
||||||
|
|
||||||
VarType type;
|
VarType type;
|
||||||
int soaWidth;
|
int soaWidth;
|
||||||
};
|
};
|
||||||
@@ -122,19 +122,19 @@ public:
|
|||||||
|
|
||||||
/** Returns true if the underlying type is either a pointer type */
|
/** Returns true if the underlying type is either a pointer type */
|
||||||
bool IsPointerType() const;
|
bool IsPointerType() const;
|
||||||
|
|
||||||
/** Returns true if the underlying type is a array type */
|
/** Returns true if the underlying type is a array type */
|
||||||
bool IsArrayType() const;
|
bool IsArrayType() const;
|
||||||
|
|
||||||
/** Returns true if the underlying type is a array type */
|
/** Returns true if the underlying type is a array type */
|
||||||
bool IsReferenceType() const;
|
bool IsReferenceType() const;
|
||||||
|
|
||||||
/** Returns true if the underlying type is either a pointer or an array */
|
/** Returns true if the underlying type is either a pointer or an array */
|
||||||
bool IsVoidType() const;
|
bool IsVoidType() const;
|
||||||
|
|
||||||
/** Returns true if this type is 'const'-qualified. */
|
/** Returns true if this type is 'const'-qualified. */
|
||||||
virtual bool IsConstType() const = 0;
|
virtual bool IsConstType() const = 0;
|
||||||
|
|
||||||
/** Returns true if the underlying type is a float or integer type. */
|
/** Returns true if the underlying type is a float or integer type. */
|
||||||
bool IsNumericType() const { return IsFloatType() || IsIntType(); }
|
bool IsNumericType() const { return IsFloatType() || IsIntType(); }
|
||||||
|
|
||||||
@@ -142,13 +142,13 @@ public:
|
|||||||
virtual Variability GetVariability() const = 0;
|
virtual Variability GetVariability() const = 0;
|
||||||
|
|
||||||
/** Returns true if the underlying type is uniform */
|
/** Returns true if the underlying type is uniform */
|
||||||
bool IsUniformType() const {
|
bool IsUniformType() const {
|
||||||
return GetVariability() == Variability::Uniform;
|
return GetVariability() == Variability::Uniform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if the underlying type is varying */
|
/** Returns true if the underlying type is varying */
|
||||||
bool IsVaryingType() const {
|
bool IsVaryingType() const {
|
||||||
return GetVariability() == Variability::Varying;
|
return GetVariability() == Variability::Varying;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if the type is laid out in "structure of arrays"
|
/** Returns true if the type is laid out in "structure of arrays"
|
||||||
@@ -161,8 +161,8 @@ public:
|
|||||||
|
|
||||||
/** Returns true if the underlying type's uniform/varying-ness is
|
/** Returns true if the underlying type's uniform/varying-ness is
|
||||||
unbound. */
|
unbound. */
|
||||||
bool HasUnboundVariability() const {
|
bool HasUnboundVariability() const {
|
||||||
return GetVariability() == Variability::Unbound;
|
return GetVariability() == Variability::Unbound;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns a type wherein any elements of the original type and
|
/* Returns a type wherein any elements of the original type and
|
||||||
@@ -196,7 +196,7 @@ public:
|
|||||||
For all other types, just returns its own type. */
|
For all other types, just returns its own type. */
|
||||||
virtual const Type *GetReferenceTarget() const;
|
virtual const Type *GetReferenceTarget() const;
|
||||||
|
|
||||||
/** Get a const version of this type. If it's already const, then the old
|
/** Get a const version of this type. If it's already const, then the old
|
||||||
Type pointer is returned. */
|
Type pointer is returned. */
|
||||||
virtual const Type *GetAsConstType() const = 0;
|
virtual const Type *GetAsConstType() const = 0;
|
||||||
|
|
||||||
@@ -244,7 +244,7 @@ public:
|
|||||||
needed.
|
needed.
|
||||||
@param reason String describing the context of why the general
|
@param reason String describing the context of why the general
|
||||||
type is needed (e.g. "+ operator").
|
type is needed (e.g. "+ operator").
|
||||||
@param forceVarying If \c true, then make sure that the returned
|
@param forceVarying If \c true, then make sure that the returned
|
||||||
type is "varying".
|
type is "varying".
|
||||||
@param vecSize The vector size of the returned type. If non-zero,
|
@param vecSize The vector size of the returned type. If non-zero,
|
||||||
the returned type will be a VectorType of the
|
the returned type will be a VectorType of the
|
||||||
@@ -254,7 +254,7 @@ public:
|
|||||||
|
|
||||||
@todo the vecSize and forceVarying parts of this should probably be
|
@todo the vecSize and forceVarying parts of this should probably be
|
||||||
factored out and done separately in the cases when needed.
|
factored out and done separately in the cases when needed.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
static const Type *MoreGeneralType(const Type *type0, const Type *type1,
|
static const Type *MoreGeneralType(const Type *type0, const Type *type1,
|
||||||
SourcePos pos, const char *reason,
|
SourcePos pos, const char *reason,
|
||||||
@@ -275,7 +275,7 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** @brief AtomicType represents basic types like floats, ints, etc.
|
/** @brief AtomicType represents basic types like floats, ints, etc.
|
||||||
|
|
||||||
AtomicTypes can be either uniform or varying. Unique instances of all
|
AtomicTypes can be either uniform or varying. Unique instances of all
|
||||||
of the possible <tt>AtomicType</tt>s are available in the static members
|
of the possible <tt>AtomicType</tt>s are available in the static members
|
||||||
@@ -313,7 +313,7 @@ public:
|
|||||||
llvm::Type *LLVMType(llvm::LLVMContext *ctx) const;
|
llvm::Type *LLVMType(llvm::LLVMContext *ctx) const;
|
||||||
llvm::DIType GetDIType(llvm::DIDescriptor scope) const;
|
llvm::DIType GetDIType(llvm::DIDescriptor scope) const;
|
||||||
|
|
||||||
/** This enumerator records the basic types that AtomicTypes can be
|
/** This enumerator records the basic types that AtomicTypes can be
|
||||||
built from. */
|
built from. */
|
||||||
enum BasicType {
|
enum BasicType {
|
||||||
TYPE_VOID,
|
TYPE_VOID,
|
||||||
@@ -431,7 +431,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
class PointerType : public Type {
|
class PointerType : public Type {
|
||||||
public:
|
public:
|
||||||
PointerType(const Type *t, Variability v, bool isConst,
|
PointerType(const Type *t, Variability v, bool isConst,
|
||||||
bool isSlice = false, bool frozen = false);
|
bool isSlice = false, bool frozen = false);
|
||||||
|
|
||||||
/** Helper method to return a uniform pointer to the given type. */
|
/** Helper method to return a uniform pointer to the given type. */
|
||||||
@@ -488,7 +488,7 @@ private:
|
|||||||
|
|
||||||
This is a common base class that StructTypes, ArrayTypes, and
|
This is a common base class that StructTypes, ArrayTypes, and
|
||||||
VectorTypes all inherit from.
|
VectorTypes all inherit from.
|
||||||
*/
|
*/
|
||||||
class CollectionType : public Type {
|
class CollectionType : public Type {
|
||||||
public:
|
public:
|
||||||
/** Returns the total number of elements in the collection. */
|
/** Returns the total number of elements in the collection. */
|
||||||
@@ -532,7 +532,7 @@ protected:
|
|||||||
|
|
||||||
ArrayType represents a one-dimensional array of instances of some other
|
ArrayType represents a one-dimensional array of instances of some other
|
||||||
type. (Multi-dimensional arrays are represented by ArrayTypes that in
|
type. (Multi-dimensional arrays are represented by ArrayTypes that in
|
||||||
turn hold ArrayTypes as their child types.)
|
turn hold ArrayTypes as their child types.)
|
||||||
*/
|
*/
|
||||||
class ArrayType : public SequentialType {
|
class ArrayType : public SequentialType {
|
||||||
public:
|
public:
|
||||||
@@ -592,7 +592,7 @@ public:
|
|||||||
any array dimensions that are unsized according to the number of
|
any array dimensions that are unsized according to the number of
|
||||||
elements in the corresponding sectoin of the initializer
|
elements in the corresponding sectoin of the initializer
|
||||||
expression.
|
expression.
|
||||||
*/
|
*/
|
||||||
static const Type *SizeUnsizedArrays(const Type *type, Expr *initExpr);
|
static const Type *SizeUnsizedArrays(const Type *type, Expr *initExpr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -663,9 +663,9 @@ private:
|
|||||||
*/
|
*/
|
||||||
class StructType : public CollectionType {
|
class StructType : public CollectionType {
|
||||||
public:
|
public:
|
||||||
StructType(const std::string &name, const llvm::SmallVector<const Type *, 8> &elts,
|
StructType(const std::string &name, const llvm::SmallVector<const Type *, 8> &elts,
|
||||||
const llvm::SmallVector<std::string, 8> &eltNames,
|
const llvm::SmallVector<std::string, 8> &eltNames,
|
||||||
const llvm::SmallVector<SourcePos, 8> &eltPositions, bool isConst,
|
const llvm::SmallVector<SourcePos, 8> &eltPositions, bool isConst,
|
||||||
Variability variability, SourcePos pos);
|
Variability variability, SourcePos pos);
|
||||||
|
|
||||||
Variability GetVariability() const;
|
Variability GetVariability() const;
|
||||||
@@ -707,7 +707,7 @@ public:
|
|||||||
|
|
||||||
/** Returns the name of the i'th element of the structure. */
|
/** Returns the name of the i'th element of the structure. */
|
||||||
const std::string &GetElementName(int i) const { return elementNames[i]; }
|
const std::string &GetElementName(int i) const { return elementNames[i]; }
|
||||||
|
|
||||||
/** Returns the total number of elements in the structure. */
|
/** Returns the total number of elements in the structure. */
|
||||||
int GetElementCount() const { return int(elementTypes.size()); }
|
int GetElementCount() const { return int(elementTypes.size()); }
|
||||||
|
|
||||||
@@ -842,9 +842,9 @@ private:
|
|||||||
*/
|
*/
|
||||||
class FunctionType : public Type {
|
class FunctionType : public Type {
|
||||||
public:
|
public:
|
||||||
FunctionType(const Type *returnType,
|
FunctionType(const Type *returnType,
|
||||||
const llvm::SmallVector<const Type *, 8> &argTypes, SourcePos pos);
|
const llvm::SmallVector<const Type *, 8> &argTypes, SourcePos pos);
|
||||||
FunctionType(const Type *returnType,
|
FunctionType(const Type *returnType,
|
||||||
const llvm::SmallVector<const Type *, 8> &argTypes,
|
const llvm::SmallVector<const Type *, 8> &argTypes,
|
||||||
const llvm::SmallVector<std::string, 8> &argNames,
|
const llvm::SmallVector<std::string, 8> &argNames,
|
||||||
const llvm::SmallVector<Expr *, 8> &argDefaults,
|
const llvm::SmallVector<Expr *, 8> &argDefaults,
|
||||||
@@ -884,7 +884,7 @@ public:
|
|||||||
function type. The \c disableMask parameter indicates whether the
|
function type. The \c disableMask parameter indicates whether the
|
||||||
llvm::FunctionType should have the trailing mask parameter, if
|
llvm::FunctionType should have the trailing mask parameter, if
|
||||||
present, removed from the return function signature. */
|
present, removed from the return function signature. */
|
||||||
llvm::FunctionType *LLVMFunctionType(llvm::LLVMContext *ctx,
|
llvm::FunctionType *LLVMFunctionType(llvm::LLVMContext *ctx,
|
||||||
bool disableMask = false) const;
|
bool disableMask = false) const;
|
||||||
|
|
||||||
int GetNumParameters() const { return (int)paramTypes.size(); }
|
int GetNumParameters() const { return (int)paramTypes.size(); }
|
||||||
@@ -915,7 +915,7 @@ public:
|
|||||||
bool isSafe;
|
bool isSafe;
|
||||||
|
|
||||||
/** If non-negative, this provides a user-supplied override to the cost
|
/** If non-negative, this provides a user-supplied override to the cost
|
||||||
function estimate for the function. */
|
function estimate for the function. */
|
||||||
int costOverride;
|
int costOverride;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -993,7 +993,7 @@ template <> inline const SequentialType *
|
|||||||
CastType(const Type *type) {
|
CastType(const Type *type) {
|
||||||
// Note that this function must be updated if other sequential type
|
// Note that this function must be updated if other sequential type
|
||||||
// implementations are added.
|
// implementations are added.
|
||||||
if (type != NULL &&
|
if (type != NULL &&
|
||||||
(type->typeId == ARRAY_TYPE || type->typeId == VECTOR_TYPE))
|
(type->typeId == ARRAY_TYPE || type->typeId == VECTOR_TYPE))
|
||||||
return (const SequentialType *)type;
|
return (const SequentialType *)type;
|
||||||
else
|
else
|
||||||
@@ -1004,7 +1004,7 @@ template <> inline const CollectionType *
|
|||||||
CastType(const Type *type) {
|
CastType(const Type *type) {
|
||||||
// Similarly a new collection type implementation requires updating
|
// Similarly a new collection type implementation requires updating
|
||||||
// this function.
|
// this function.
|
||||||
if (type != NULL &&
|
if (type != NULL &&
|
||||||
(type->typeId == ARRAY_TYPE || type->typeId == VECTOR_TYPE ||
|
(type->typeId == ARRAY_TYPE || type->typeId == VECTOR_TYPE ||
|
||||||
type->typeId == STRUCT_TYPE))
|
type->typeId == STRUCT_TYPE))
|
||||||
return (const CollectionType *)type;
|
return (const CollectionType *)type;
|
||||||
|
|||||||
24
util.cpp
24
util.cpp
@@ -28,7 +28,7 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file util.cpp
|
/** @file util.cpp
|
||||||
@@ -139,7 +139,7 @@ lResetColor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Given a pointer into a string, find the end of the current word and
|
/** Given a pointer into a string, find the end of the current word and
|
||||||
return a pointer to its last character.
|
return a pointer to its last character.
|
||||||
*/
|
*/
|
||||||
static const char *
|
static const char *
|
||||||
lFindWordEnd(const char *buf) {
|
lFindWordEnd(const char *buf) {
|
||||||
@@ -166,7 +166,7 @@ lPrintFileLineContext(SourcePos p) {
|
|||||||
while ((c = fgetc(f)) != EOF) {
|
while ((c = fgetc(f)) != EOF) {
|
||||||
// Don't print more than three lines of context. (More than that,
|
// Don't print more than three lines of context. (More than that,
|
||||||
// and we're probably doing the wrong thing...)
|
// and we're probably doing the wrong thing...)
|
||||||
if (curLine >= std::max(p.first_line, p.last_line-2) &&
|
if (curLine >= std::max(p.first_line, p.last_line-2) &&
|
||||||
curLine <= p.last_line)
|
curLine <= p.last_line)
|
||||||
fputc(c, stderr);
|
fputc(c, stderr);
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
@@ -322,7 +322,7 @@ asprintf(char **sptr, const char *fmt, ...)
|
|||||||
@param args Arguments with values for format string % entries
|
@param args Arguments with values for format string % entries
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
|
lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
|
||||||
va_list args) {
|
va_list args) {
|
||||||
char *errorBuf, *formattedBuf;
|
char *errorBuf, *formattedBuf;
|
||||||
if (vasprintf(&errorBuf, fmt, args) == -1) {
|
if (vasprintf(&errorBuf, fmt, args) == -1) {
|
||||||
@@ -335,7 +335,7 @@ lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
|
|||||||
// We don't have a valid SourcePos, so create a message without it
|
// We don't have a valid SourcePos, so create a message without it
|
||||||
if (asprintf(&formattedBuf, "%s%s%s%s%s: %s%s", lStartBold(),
|
if (asprintf(&formattedBuf, "%s%s%s%s%s: %s%s", lStartBold(),
|
||||||
isError ? lStartRed() : lStartBlue(), type,
|
isError ? lStartRed() : lStartBlue(), type,
|
||||||
lResetColor(), lStartBold(), errorBuf,
|
lResetColor(), lStartBold(), errorBuf,
|
||||||
lResetColor()) == -1) {
|
lResetColor()) == -1) {
|
||||||
fprintf(stderr, "asprintf() unable to allocate memory!\n");
|
fprintf(stderr, "asprintf() unable to allocate memory!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -344,10 +344,10 @@ lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Create an error message that includes the file and line number
|
// Create an error message that includes the file and line number
|
||||||
if (asprintf(&formattedBuf, "%s%s:%d:%d: %s%s%s%s: %s%s",
|
if (asprintf(&formattedBuf, "%s%s:%d:%d: %s%s%s%s: %s%s",
|
||||||
lStartBold(), p.name, p.first_line, p.first_column,
|
lStartBold(), p.name, p.first_line, p.first_column,
|
||||||
isError ? lStartRed() : lStartBlue(), type,
|
isError ? lStartRed() : lStartBlue(), type,
|
||||||
lResetColor(), lStartBold(), errorBuf,
|
lResetColor(), lStartBold(), errorBuf,
|
||||||
lResetColor()) == -1) {
|
lResetColor()) == -1) {
|
||||||
fprintf(stderr, "asprintf() unable to allocate memory!\n");
|
fprintf(stderr, "asprintf() unable to allocate memory!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -507,7 +507,7 @@ StringEditDistance(const std::string &str1, const std::string &str2, int maxDist
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
MatchStrings(const std::string &str, const std::vector<std::string> &options) {
|
MatchStrings(const std::string &str, const std::vector<std::string> &options) {
|
||||||
if (str.size() == 0 || (str.size() == 1 && !isalpha(str[0])))
|
if (str.size() == 0 || (str.size() == 1 && !isalpha(str[0])))
|
||||||
// don't even try...
|
// don't even try...
|
||||||
@@ -536,7 +536,7 @@ MatchStrings(const std::string &str, const std::vector<std::string> &options) {
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GetDirectoryAndFileName(const std::string ¤tDirectory,
|
GetDirectoryAndFileName(const std::string ¤tDirectory,
|
||||||
const std::string &relativeName,
|
const std::string &relativeName,
|
||||||
std::string *directory, std::string *filename) {
|
std::string *directory, std::string *filename) {
|
||||||
#ifdef ISPC_IS_WINDOWS
|
#ifdef ISPC_IS_WINDOWS
|
||||||
@@ -550,7 +550,7 @@ GetDirectoryAndFileName(const std::string ¤tDirectory,
|
|||||||
#else
|
#else
|
||||||
// We need a fully qualified path. First, see if the current file name
|
// We need a fully qualified path. First, see if the current file name
|
||||||
// is fully qualified itself--in that case, the current working
|
// is fully qualified itself--in that case, the current working
|
||||||
// directory isn't needed.
|
// directory isn't needed.
|
||||||
// @todo This probably needs to be smarter for Windows...
|
// @todo This probably needs to be smarter for Windows...
|
||||||
std::string fullPath;
|
std::string fullPath;
|
||||||
if (relativeName[0] == '/')
|
if (relativeName[0] == '/')
|
||||||
|
|||||||
16
util.h
16
util.h
@@ -28,12 +28,12 @@
|
|||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file util.h
|
/** @file util.h
|
||||||
|
|
||||||
@brief
|
@brief
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ISPC_UTIL_H
|
#ifndef ISPC_UTIL_H
|
||||||
@@ -50,9 +50,9 @@ struct SourcePos;
|
|||||||
of two already. */
|
of two already. */
|
||||||
inline uint32_t RoundUpPow2(uint32_t v) {
|
inline uint32_t RoundUpPow2(uint32_t v) {
|
||||||
v--;
|
v--;
|
||||||
v |= v >> 1;
|
v |= v >> 1;
|
||||||
v |= v >> 2;
|
v |= v >> 2;
|
||||||
v |= v >> 4;
|
v |= v >> 4;
|
||||||
v |= v >> 8;
|
v |= v >> 8;
|
||||||
v |= v >> 16;
|
v |= v >> 16;
|
||||||
return v+1;
|
return v+1;
|
||||||
@@ -75,7 +75,7 @@ int asprintf(char **sptr, const char *fmt, ...);
|
|||||||
g->debugPrint is \c true. In addition to a program source code
|
g->debugPrint is \c true. In addition to a program source code
|
||||||
position to associate with the message, a printf()-style format string
|
position to associate with the message, a printf()-style format string
|
||||||
is passed along with any values needed for items in the format
|
is passed along with any values needed for items in the format
|
||||||
string.
|
string.
|
||||||
*/
|
*/
|
||||||
void Debug(SourcePos p, const char *format, ...) PRINTF_FUNC;
|
void Debug(SourcePos p, const char *format, ...) PRINTF_FUNC;
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ void Warning(SourcePos p, const char *format, ...) PRINTF_FUNC;
|
|||||||
able to issue any subsequent error messages. In addition to a program
|
able to issue any subsequent error messages. In addition to a program
|
||||||
source code position to associate with the message, a printf()-style
|
source code position to associate with the message, a printf()-style
|
||||||
format string is passed along with any values needed for items in the
|
format string is passed along with any values needed for items in the
|
||||||
format string.
|
format string.
|
||||||
*/
|
*/
|
||||||
void Error(SourcePos p, const char *format, ...) PRINTF_FUNC;
|
void Error(SourcePos p, const char *format, ...) PRINTF_FUNC;
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ void Error(SourcePos p, const char *format, ...) PRINTF_FUNC;
|
|||||||
completion of compilation. In addition to a program source code
|
completion of compilation. In addition to a program source code
|
||||||
position to associate with the message, a printf()-style format string
|
position to associate with the message, a printf()-style format string
|
||||||
is passed along with any values needed for items in the format
|
is passed along with any values needed for items in the format
|
||||||
string.
|
string.
|
||||||
*/
|
*/
|
||||||
void PerformanceWarning(SourcePos p, const char *format, ...) PRINTF_FUNC;
|
void PerformanceWarning(SourcePos p, const char *format, ...) PRINTF_FUNC;
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ std::vector<std::string> MatchStrings(const std::string &str,
|
|||||||
/** Given the current working directory and a filename relative to that
|
/** Given the current working directory and a filename relative to that
|
||||||
directory, this function returns the final directory that the resulting
|
directory, this function returns the final directory that the resulting
|
||||||
file is in and the base name of the file itself. */
|
file is in and the base name of the file itself. */
|
||||||
void GetDirectoryAndFileName(const std::string ¤tDir,
|
void GetDirectoryAndFileName(const std::string ¤tDir,
|
||||||
const std::string &relativeName,
|
const std::string &relativeName,
|
||||||
std::string *directory, std::string *filename);
|
std::string *directory, std::string *filename);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user