Intel SPMD Program Compiler  1.3.0
module.cpp
Go to the documentation of this file.
00001 /*
00002   Copyright (c) 2010-2012, Intel Corporation
00003   All rights reserved.
00004 
00005   Redistribution and use in source and binary forms, with or without
00006   modification, are permitted provided that the following conditions are
00007   met:
00008 
00009     * Redistributions of source code must retain the above copyright
00010       notice, this list of conditions and the following disclaimer.
00011 
00012     * Redistributions in binary form must reproduce the above copyright
00013       notice, this list of conditions and the following disclaimer in the
00014       documentation and/or other materials provided with the distribution.
00015 
00016     * Neither the name of Intel Corporation nor the names of its
00017       contributors may be used to endorse or promote products derived from
00018       this software without specific prior written permission.
00019 
00020 
00021    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00022    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00023    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00024    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00025    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00026    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00027    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00028    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00029    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00030    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
00032 */
00033 
00034 /** @file module.cpp
00035     @brief Impementation of the Module class, which collects the result of compiling
00036            a source file and then generates output (object files, etc.)
00037 */
00038 
00039 #include "module.h"
00040 #include "util.h"
00041 #include "ctx.h"
00042 #include "func.h"
00043 #include "builtins.h"
00044 #include "type.h"
00045 #include "expr.h"
00046 #include "sym.h"
00047 #include "stmt.h"
00048 #include "opt.h"
00049 #include "llvmutil.h"
00050 
00051 #include <stdio.h>
00052 #include <stdarg.h>
00053 #include <ctype.h>
00054 #include <sys/types.h>
00055 #include <sys/stat.h>
00056 #include <fcntl.h>
00057 #include <algorithm>
00058 #include <set>
00059 #include <sstream>
00060 #include <iostream>
00061 #ifdef ISPC_IS_WINDOWS
00062 #include <windows.h>
00063 #include <io.h>
00064 #define strcasecmp stricmp
00065 #endif
00066 
00067 #include <llvm/LLVMContext.h>
00068 #include <llvm/Module.h>
00069 #include <llvm/Type.h>
00070 #include <llvm/DerivedTypes.h>
00071 #include <llvm/Instructions.h>
00072 #include <llvm/Intrinsics.h>
00073 #include <llvm/PassManager.h>
00074 #include <llvm/PassRegistry.h>
00075 #include <llvm/Transforms/IPO.h>
00076 #include <llvm/Support/FormattedStream.h>
00077 #include <llvm/Support/FileUtilities.h>
00078 #include <llvm/Target/TargetMachine.h>
00079 #include <llvm/Target/TargetOptions.h>
00080 #include <llvm/Target/TargetData.h>
00081 #include <llvm/Analysis/Verifier.h>
00082 #include <llvm/Support/CFG.h>
00083 #include <clang/Frontend/CompilerInstance.h>
00084 #include <clang/Frontend/TextDiagnosticPrinter.h>
00085 #include <clang/Frontend/Utils.h>
00086 #include <clang/Basic/TargetInfo.h>
00087 #include <llvm/Support/ToolOutputFile.h>
00088 #include <llvm/Support/Host.h>
00089 #include <llvm/Assembly/PrintModulePass.h>
00090 #include <llvm/Support/raw_ostream.h>
00091 #include <llvm/Bitcode/ReaderWriter.h>
00092 
00093 /*! list of files encountered by the parser. this allows emitting of
00094     the module file's dependencies via the -MMM option */
00095 std::set<std::string> registeredDependencies;
00096 
00097 /*! this is where the parser tells us that it has seen the given file
00098     name in the CPP hash */
00099 void RegisterDependency(const std::string &fileName)
00100 {
00101   if (fileName[0] != '<' && fileName != "stdlib.ispc")
00102     registeredDependencies.insert(fileName);
00103 }
00104 
00105 static void
00106 lDeclareSizeAndPtrIntTypes(SymbolTable *symbolTable) {
00107     const Type *ptrIntType = (g->target.is32Bit) ? AtomicType::VaryingInt32 :
00108         AtomicType::VaryingInt64;
00109     ptrIntType = ptrIntType->GetAsUnboundVariabilityType();
00110 
00111     symbolTable->AddType("intptr_t", ptrIntType, SourcePos());
00112     symbolTable->AddType("uintptr_t", ptrIntType->GetAsUnsignedType(),
00113                          SourcePos());
00114     symbolTable->AddType("ptrdiff_t", ptrIntType, SourcePos());
00115 
00116     const Type *sizeType = (g->target.is32Bit || g->opt.force32BitAddressing) ?
00117         AtomicType::VaryingUInt32 : AtomicType::VaryingUInt64;
00118     sizeType = sizeType->GetAsUnboundVariabilityType();
00119     symbolTable->AddType("size_t", sizeType, SourcePos());
00120 }
00121 
00122 
00123 /** After compilation completes, there's often a lot of extra debugging
00124     metadata left around that isn't needed any more--for example, for
00125     static functions that weren't actually used, function information for
00126     functions that were inlined, etc.  This function takes a llvm::Module
00127     and tries to strip out all of this extra stuff.
00128  */
00129 static void
00130 lStripUnusedDebugInfo(llvm::Module *module) {
00131     if (g->generateDebuggingSymbols == false)
00132         return;
00133 
00134 #ifndef LLVM_3_0
00135     // loop over the compile units that contributed to the final module
00136     if (llvm::NamedMDNode *cuNodes = module->getNamedMetadata("llvm.dbg.cu")) {
00137         for (unsigned i = 0, ie = cuNodes->getNumOperands(); i != ie; ++i) {
00138             llvm::MDNode *cuNode = cuNodes->getOperand(i);
00139             llvm::DICompileUnit cu(cuNode);
00140             llvm::DIArray subprograms = cu.getSubprograms();
00141             std::vector<llvm::Value *> usedSubprograms;
00142 
00143             if (subprograms.getNumElements() == 0)
00144                 continue;
00145 
00146             // And now loop over the subprograms inside each compile unit.
00147             for (unsigned j = 0, je = subprograms.getNumElements(); j != je; ++j) {
00148                 llvm::MDNode *spNode = 
00149                     llvm::dyn_cast<llvm::MDNode>(subprograms->getOperand(j));
00150                 Assert(spNode != NULL);
00151                 llvm::DISubprogram sp(spNode);
00152 
00153                 // Get the name of the subprogram.  Start with the mangled
00154                 // name; if that's empty then we have an export'ed
00155                 // function, so grab the unmangled name in that case.
00156                 std::string name = sp.getLinkageName();
00157                 if (name == "")
00158                     name = sp.getName();
00159 
00160                 // Does the llvm::Function for this function survive in the
00161                 // module?
00162                 if (module->getFunction(name) != NULL)
00163                     usedSubprograms.push_back(sp);
00164             }
00165 
00166             Debug(SourcePos(), "%d / %d functions left in module with debug "
00167                   "info.", (int)usedSubprograms.size(),
00168                   (int)subprograms.getNumElements());
00169 
00170             // We'd now like to replace the array of subprograms in the
00171             // compile unit with only the ones that actually have function
00172             // definitions present.  Unfortunately, llvm::DICompileUnit
00173             // doesn't provide a method to set the subprograms.  Therefore,
00174             // we end up needing to directly stuff a new array into the
00175             // appropriate slot (number 12) in the MDNode for the compile
00176             // unit.
00177             //
00178             // Because this is all so hard-coded and would break if the
00179             // debugging metadata organization on the LLVM side changed,
00180             // here is a bunch of asserting to make sure that element 12 of
00181             // the compile unit's MDNode has the subprograms array....
00182             llvm::MDNode *nodeSPMD = 
00183                 llvm::dyn_cast<llvm::MDNode>(cuNode->getOperand(12));
00184             Assert(nodeSPMD != NULL);
00185             llvm::MDNode *nodeSPMDArray =
00186                 llvm::dyn_cast<llvm::MDNode>(nodeSPMD->getOperand(0));
00187             llvm::DIArray nodeSPs(nodeSPMDArray);
00188             Assert(nodeSPs.getNumElements() == subprograms.getNumElements());
00189             for (int i = 0; i < (int)nodeSPs.getNumElements(); ++i)
00190                 Assert(nodeSPs.getElement(i) == subprograms.getElement(i));
00191 
00192             // And now we can go and stuff it into the node with some
00193             // confidence...
00194             llvm::Value *usedSubprogramsArray = 
00195                 m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(usedSubprograms));
00196             llvm::MDNode *replNode = 
00197                 llvm::MDNode::get(*g->ctx, llvm::ArrayRef<llvm::Value *>(usedSubprogramsArray));
00198             cuNode->replaceOperandWith(12, replNode);
00199         }
00200     }
00201 
00202     // Also, erase a bunch of named metadata detrius; for each function
00203     // there is sometimes named metadata llvm.dbg.lv.{funcname} that
00204     // doesn't seem to be otherwise needed.
00205     std::vector<llvm::NamedMDNode *> toErase;
00206     llvm::Module::named_metadata_iterator iter = module->named_metadata_begin();
00207     for (; iter != module->named_metadata_end(); ++iter) {
00208         if (!strncmp(iter->getName().str().c_str(), "llvm.dbg.lv", 11))
00209             toErase.push_back(iter);
00210     }
00211     for (int i = 0; i < (int)toErase.size(); ++i)
00212         module->eraseNamedMetadata(toErase[i]);
00213 #endif // !LLVM_3_0
00214 
00215     // Wrap up by running the LLVM pass to remove anything left that's
00216     // unused.
00217     llvm::PassManager pm;
00218     pm.add(llvm::createStripDeadDebugInfoPass());
00219     pm.run(*module);
00220 }
00221 
00222 
00223 ///////////////////////////////////////////////////////////////////////////
00224 // Module
00225 
00226 Module::Module(const char *fn) {
00227     // It's a hack to do this here, but it must be done after the target
00228     // information has been set (so e.g. the vector width is known...)  In
00229     // particular, if we're compiling to multiple targets with different
00230     // vector widths, this needs to be redone each time through.
00231     InitLLVMUtil(g->ctx, g->target);
00232 
00233     filename = fn;
00234     errorCount = 0;
00235     symbolTable = new SymbolTable;
00236     ast = new AST;
00237 
00238     lDeclareSizeAndPtrIntTypes(symbolTable);
00239 
00240     module = new llvm::Module(filename ? filename : "<stdin>", *g->ctx);
00241     module->setTargetTriple(g->target.GetTripleString());
00242 
00243     if (g->target.isa == Target::GENERIC) {
00244         // <16 x i1> vectors only need 16 bit / 2 byte alignment
00245         std::string datalayout = module->getDataLayout();
00246         datalayout += "v16:16:16";
00247         module->setDataLayout(datalayout);
00248     }
00249 
00250     if (g->generateDebuggingSymbols) {
00251         diBuilder = new llvm::DIBuilder(*module);
00252 
00253         // Let the DIBuilder know that we're starting a new compilation
00254         // unit.
00255         if (filename == NULL) {
00256             // Unfortunately we can't yet call Error() since the global 'm'
00257             // variable hasn't been initialized yet.
00258             fprintf(stderr, "Can't emit debugging information with no "
00259                     "source file on disk.\n");
00260             ++errorCount;
00261             delete diBuilder;
00262             diBuilder = NULL;
00263         }
00264         else {
00265             std::string directory, name;
00266             GetDirectoryAndFileName(g->currentDirectory, filename, &directory,
00267                                     &name);
00268             char producerString[512];
00269 #if defined(BUILD_VERSION) && defined (BUILD_DATE)
00270             sprintf(producerString, "ispc version %s (build %s on %s)",
00271                     ISPC_VERSION, BUILD_VERSION, BUILD_DATE);
00272 #else
00273             sprintf(producerString, "ispc version %s (built on %s)",
00274                     ISPC_VERSION, __DATE__);
00275 #endif
00276             diBuilder->createCompileUnit(llvm::dwarf::DW_LANG_C99,  /* lang */
00277                                          name,  /* filename */
00278                                          directory, /* directory */
00279                                          producerString, /* producer */
00280                                          g->opt.level > 0 /* is optimized */,
00281                                          "-g", /* command line args */
00282                                          0 /* run time version */);
00283         }
00284     }
00285     else
00286         diBuilder = NULL;
00287 }
00288 
00289 
00290 extern FILE *yyin;
00291 extern int yyparse();
00292 typedef struct yy_buffer_state *YY_BUFFER_STATE;
00293 extern void yy_switch_to_buffer(YY_BUFFER_STATE);
00294 extern YY_BUFFER_STATE yy_scan_string(const char *);
00295 extern YY_BUFFER_STATE yy_create_buffer(FILE *, int);
00296 extern void yy_delete_buffer(YY_BUFFER_STATE);
00297 
00298 int
00299 Module::CompileFile() {
00300     extern void ParserInit();
00301     ParserInit();
00302 
00303     // FIXME: it'd be nice to do this in the Module constructor, but this
00304     // function ends up calling into routines that expect the global
00305     // variable 'm' to be initialized and available (which it isn't until
00306     // the Module constructor returns...)
00307     DefineStdlib(symbolTable, g->ctx, module, g->includeStdlib);
00308 
00309     bool runPreprocessor = g->runCPP;
00310 
00311     if (runPreprocessor) {
00312         if (filename != NULL) {
00313             // Try to open the file first, since otherwise we crash in the
00314             // preprocessor if the file doesn't exist.
00315             FILE *f = fopen(filename, "r");
00316             if (!f) {
00317                 perror(filename);
00318                 return 1;
00319             }
00320             fclose(f);
00321         }
00322 
00323         std::string buffer;
00324         llvm::raw_string_ostream os(buffer);
00325         execPreprocessor((filename != NULL) ? filename : "-", &os);
00326         YY_BUFFER_STATE strbuf = yy_scan_string(os.str().c_str());
00327         yyparse();
00328         yy_delete_buffer(strbuf);
00329     }
00330     else {
00331         // No preprocessor, just open up the file if it's not stdin..
00332         FILE* f = NULL;
00333         if (filename == NULL) 
00334             f = stdin;
00335         else {
00336             f = fopen(filename, "r");
00337             if (f == NULL) {
00338                 perror(filename);
00339                 return 1;
00340             }
00341         }
00342         yyin = f;
00343         yy_switch_to_buffer(yy_create_buffer(yyin, 4096));
00344         yyparse();
00345         fclose(f);
00346     }
00347 
00348     ast->GenerateIR();
00349 
00350     if (errorCount == 0)
00351         Optimize(module, g->opt.level);
00352 
00353     return errorCount;
00354 }
00355 
00356 
00357 void
00358 Module::AddTypeDef(const std::string &name, const Type *type,
00359                    SourcePos pos) {
00360     // Typedefs are easy; just add the mapping between the given name and
00361     // the given type.
00362     symbolTable->AddType(name.c_str(), type, pos);
00363 }
00364 
00365 
00366 void
00367 Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initExpr, 
00368                           bool isConst, StorageClass storageClass, SourcePos pos) {
00369     // These may be NULL due to errors in parsing; just gracefully return
00370     // here if so.
00371     if (name == "" || type == NULL) {
00372         Assert(errorCount > 0);
00373         return;
00374     }
00375 
00376     if (symbolTable->LookupFunction(name.c_str())) {
00377         Error(pos, "Global variable \"%s\" shadows previously-declared "
00378               "function.", name.c_str());
00379         return;
00380     }
00381 
00382     if (storageClass == SC_EXTERN_C) {
00383         Error(pos, "extern \"C\" qualifier can only be used for "
00384               "functions.");
00385         return;
00386     }
00387 
00388     if (Type::Equal(type, AtomicType::Void)) {
00389         Error(pos, "\"void\" type global variable is illegal.");
00390         return;
00391     }
00392 
00393     type = ArrayType::SizeUnsizedArrays(type, initExpr);
00394     if (type == NULL)
00395         return;
00396 
00397     const ArrayType *at = CastType<ArrayType>(type);
00398     if (at != NULL && at->TotalElementCount() == 0) {
00399         Error(pos, "Illegal to declare a global variable with unsized "
00400               "array dimensions that aren't set with an initializer "
00401               "expression.");
00402         return;
00403     }
00404         
00405     llvm::Type *llvmType = type->LLVMType(g->ctx);
00406     if (llvmType == NULL)
00407         return;
00408 
00409     // See if we have an initializer expression for the global.  If so,
00410     // make sure it's a compile-time constant!
00411     llvm::Constant *llvmInitializer = NULL;
00412     ConstExpr *constValue = NULL;
00413     if (storageClass == SC_EXTERN || storageClass == SC_EXTERN_C) {
00414         if (initExpr != NULL)
00415             Error(pos, "Initializer can't be provided with \"extern\" "
00416                   "global variable \"%s\".", name.c_str());
00417     }
00418     else {
00419         if (initExpr != NULL) {
00420             initExpr = TypeCheck(initExpr);
00421             if (initExpr != NULL) {
00422                 // We need to make sure the initializer expression is
00423                 // the same type as the global.  (But not if it's an
00424                 // ExprList; they don't have types per se / can't type
00425                 // convert themselves anyway.)
00426                 if (dynamic_cast<ExprList *>(initExpr) == NULL)
00427                     initExpr = TypeConvertExpr(initExpr, type, "initializer");
00428             
00429                 if (initExpr != NULL) {
00430                     initExpr = Optimize(initExpr);
00431                     // Fingers crossed, now let's see if we've got a
00432                     // constant value..
00433                     llvmInitializer = initExpr->GetConstant(type);
00434 
00435                     if (llvmInitializer != NULL) {
00436                         if (type->IsConstType())
00437                             // Try to get a ConstExpr associated with
00438                             // the symbol.  This dynamic_cast can
00439                             // validly fail, for example for types like
00440                             // StructTypes where a ConstExpr can't
00441                             // represent their values.
00442                             constValue = dynamic_cast<ConstExpr *>(initExpr);
00443                     }
00444                     else
00445                         Error(initExpr->pos, "Initializer for global variable \"%s\" "
00446                               "must be a constant.", name.c_str());
00447                 }
00448             }
00449         }
00450 
00451         // If no initializer was provided or if we couldn't get a value
00452         // above, initialize it with zeros..
00453         if (llvmInitializer == NULL)
00454             llvmInitializer = llvm::Constant::getNullValue(llvmType);
00455     }
00456 
00457     Symbol *sym = symbolTable->LookupVariable(name.c_str());
00458     llvm::GlobalVariable *oldGV = NULL;
00459     if (sym != NULL) {
00460         // We've already seen either a declaration or a definition of this
00461         // global.
00462 
00463         // If the type doesn't match with the previous one, issue an error.
00464         if (!Type::Equal(sym->type, type) ||
00465             (sym->storageClass != SC_EXTERN && 
00466              sym->storageClass != SC_EXTERN_C &&
00467              sym->storageClass != storageClass)) {
00468             Error(pos, "Definition of variable \"%s\" conflicts with "
00469                   "definition at %s:%d.", name.c_str(), 
00470                   sym->pos.name, sym->pos.first_line);
00471             return;
00472         }
00473 
00474         llvm::GlobalVariable *gv = 
00475             llvm::dyn_cast<llvm::GlobalVariable>(sym->storagePtr);
00476         Assert(gv != NULL);
00477 
00478         // And issue an error if this is a redefinition of a variable
00479         if (gv->hasInitializer() && 
00480             sym->storageClass != SC_EXTERN && sym->storageClass != SC_EXTERN_C) {
00481             Error(pos, "Redefinition of variable \"%s\" is illegal. "
00482                   "(Previous definition at %s:%d.)", sym->name.c_str(),
00483                   sym->pos.name, sym->pos.first_line);
00484             return;
00485         }
00486 
00487         // Now, we either have a redeclaration of a global, or a definition
00488         // of a previously-declared global.  First, save the pointer to the
00489         // previous llvm::GlobalVariable
00490         oldGV = gv;
00491     }
00492     else {
00493         sym = new Symbol(name, pos, type, storageClass);
00494         symbolTable->AddVariable(sym);
00495     }
00496     sym->constValue = constValue;
00497 
00498     llvm::GlobalValue::LinkageTypes linkage =
00499         (sym->storageClass == SC_STATIC) ? llvm::GlobalValue::InternalLinkage :
00500         llvm::GlobalValue::ExternalLinkage;
00501 
00502     // Note that the NULL llvmInitializer is what leads to "extern"
00503     // declarations coming up extern and not defining storage (a bit
00504     // subtle)...
00505     sym->storagePtr = new llvm::GlobalVariable(*module, llvmType, isConst, 
00506                                                linkage, llvmInitializer, 
00507                                                sym->name.c_str());
00508 
00509     // Patch up any references to the previous GlobalVariable (e.g. from a
00510     // declaration of a global that was later defined.)
00511     if (oldGV != NULL) {
00512         oldGV->replaceAllUsesWith(sym->storagePtr);
00513         oldGV->removeFromParent();
00514         sym->storagePtr->setName(sym->name.c_str());
00515     }
00516     
00517     if (diBuilder) {
00518         llvm::DIFile file = pos.GetDIFile();
00519         llvm::DIGlobalVariable var =
00520             diBuilder->createGlobalVariable(name, 
00521                                             file,
00522                                             pos.first_line,
00523                                             sym->type->GetDIType(file),
00524                                             (sym->storageClass == SC_STATIC),
00525                                             sym->storagePtr);
00526         Assert(var.Verify());
00527     }
00528 }
00529 
00530 
00531 /** Given an arbitrary type, see if it or any of the leaf types contained
00532     in it has a type that's illegal to have exported to C/C++
00533     code--specifically, that it has a varying value in memory, or a pointer
00534     to SOA data (which has a different representation than a regular
00535     pointer.
00536 
00537     (Note that it's fine for the original struct or a contained struct to
00538     be varying, so long as all of its members have bound 'uniform'
00539     variability.) 
00540 
00541     This functions returns true and issues an error if are any illegal
00542     types are found and returns false otherwise.  
00543 */
00544 static bool
00545 lRecursiveCheckValidParamType(const Type *t) {
00546     const StructType *st = CastType<StructType>(t);
00547     if (st != NULL) {
00548         for (int i = 0; i < st->GetElementCount(); ++i)
00549             if (lRecursiveCheckValidParamType(st->GetElementType(i)))
00550                 return true;
00551         return false;
00552     }
00553 
00554     const SequentialType *seqt = CastType<SequentialType>(t);
00555     if (seqt != NULL)
00556         return lRecursiveCheckValidParamType(seqt->GetElementType());
00557 
00558     const PointerType *pt = CastType<PointerType>(t);
00559     if (pt != NULL) {
00560         if (pt->IsSlice() || pt->IsVaryingType())
00561             return true;
00562         return lRecursiveCheckValidParamType(pt->GetBaseType());
00563     }
00564 
00565     return t->IsVaryingType();
00566 }
00567 
00568 
00569 /** Given a Symbol representing a function parameter, see if it or any
00570     contained types are varying.  If so, issue an error.  (This function
00571     should only be called for parameters to 'export'ed functions, where
00572     varying parameters is illegal.
00573  */
00574 static void
00575 lCheckForVaryingParameter(const Type *type, const std::string &name, 
00576                           SourcePos pos) {
00577     if (lRecursiveCheckValidParamType(type)) {
00578         if (CastType<PointerType>(type))
00579             Error(pos, "Varying pointer type parameter \"%s\" is illegal "
00580                   "in an exported function.", name.c_str());
00581         else if (CastType<StructType>(type->GetBaseType()))
00582             Error(pos, "Struct parameter \"%s\" with varying member(s) is illegal "
00583                   "in an exported function.", name.c_str());
00584         else
00585             Error(pos, "Varying parameter \"%s\" is illegal in an exported function.",
00586                   name.c_str());
00587     }
00588 }
00589 
00590 
00591 /** Given a function type, loop through the function parameters and see if
00592     any are StructTypes.  If so, issue an error; this is currently broken
00593     (https://github.com/ispc/ispc/issues/3).
00594  */
00595 static void
00596 lCheckForStructParameters(const FunctionType *ftype, SourcePos pos) {
00597     for (int i = 0; i < ftype->GetNumParameters(); ++i) {
00598         const Type *type = ftype->GetParameterType(i);
00599         if (CastType<StructType>(type) != NULL) {
00600             Error(pos, "Passing structs to/from application functions is "
00601                   "currently broken.  Use a pointer or const pointer to the "
00602                   "struct instead for now.");
00603             return;
00604         }
00605     }
00606 }
00607 
00608 
00609 /** We've got a declaration for a function to process.  This function does
00610     all the work of creating the corresponding llvm::Function instance,
00611     adding the symbol for the function to the symbol table and doing
00612     various sanity checks.  This function returns true upon success and
00613     false if any errors were encountered.
00614  */
00615 void
00616 Module::AddFunctionDeclaration(const std::string &name, 
00617                                const FunctionType *functionType, 
00618                                StorageClass storageClass, bool isInline,
00619                                SourcePos pos) {
00620     Assert(functionType != NULL);
00621 
00622     // If a global variable with the same name has already been declared
00623     // issue an error.
00624     if (symbolTable->LookupVariable(name.c_str()) != NULL) {
00625         Error(pos, "Function \"%s\" shadows previously-declared global variable. "
00626               "Ignoring this definition.",
00627               name.c_str());
00628         return;
00629     }
00630 
00631     std::vector<Symbol *> overloadFuncs;
00632     symbolTable->LookupFunction(name.c_str(), &overloadFuncs);
00633     if (overloadFuncs.size() > 0) {
00634         for (unsigned int i = 0; i < overloadFuncs.size(); ++i) {
00635             Symbol *overloadFunc = overloadFuncs[i];
00636 
00637             const FunctionType *overloadType = 
00638                 CastType<FunctionType>(overloadFunc->type);
00639             if (overloadType == NULL) {
00640                 Assert(m->errorCount == 0);
00641                 continue;
00642             }
00643 
00644             // Check for a redeclaration of a function with the same name
00645             // and type.  This also hits when we have previously declared
00646             // the function and are about to define it.
00647             if (Type::Equal(overloadFunc->type, functionType))
00648                 return;
00649 
00650             if (functionType->isExported || overloadType->isExported)
00651                 Error(pos, "Illegal to provide \"export\" qualifier for "
00652                       "functions with the same name but different types. "
00653                       "(Previous function declaration (%s:%d).)",
00654                       overloadFunc->pos.name, overloadFunc->pos.first_line);
00655 
00656             // If all of the parameter types match but the return type is
00657             // different, return an error--overloading by return type isn't
00658             // allowed.
00659             const FunctionType *ofType = 
00660                 CastType<FunctionType>(overloadFunc->type);
00661             Assert(ofType != NULL);
00662             if (ofType->GetNumParameters() == functionType->GetNumParameters()) {
00663                 int i;
00664                 for (i = 0; i < functionType->GetNumParameters(); ++i) {
00665                     if (Type::Equal(ofType->GetParameterType(i),
00666                                     functionType->GetParameterType(i)) == false)
00667                         break;
00668                 }
00669                 if (i == functionType->GetNumParameters()) {
00670                     std::string thisRetType = functionType->GetReturnTypeString();
00671                     std::string otherRetType = ofType->GetReturnTypeString();
00672                     Error(pos, "Illegal to overload function by return "
00673                           "type only.  This function returns \"%s\" while "
00674                           "previous declaration at %s:%d returns \"%s\".",
00675                           thisRetType.c_str(), overloadFunc->pos.name,
00676                           overloadFunc->pos.first_line, otherRetType.c_str());
00677                     return;
00678                 }
00679             }
00680         }
00681     }
00682 
00683     if (storageClass == SC_EXTERN_C) {
00684         // Make sure the user hasn't supplied both an 'extern "C"' and a
00685         // 'task' qualifier with the function
00686         if (functionType->isTask) {
00687             Error(pos, "\"task\" qualifier is illegal with C-linkage extern "
00688                   "function \"%s\".  Ignoring this function.", name.c_str());
00689             return;
00690         }
00691 
00692         std::vector<Symbol *> funcs;
00693         symbolTable->LookupFunction(name.c_str(), &funcs);
00694         if (funcs.size() > 0) {
00695             if (funcs.size() > 1) {
00696                 // Multiple functions with this name have already been declared; 
00697                 // can't overload here
00698                 Error(pos, "Can't overload extern \"C\" function \"%s\"; "
00699                       "%d functions with the same name have already been declared.",
00700                       name.c_str(), (int)funcs.size());
00701                 return;
00702             }
00703 
00704             // One function with the same name has been declared; see if it
00705             // has the same type as this one, in which case it's ok.
00706             if (Type::Equal(funcs[0]->type, functionType))
00707                 return;
00708             else {
00709                 Error(pos, "Can't overload extern \"C\" function \"%s\".",
00710                       name.c_str());
00711                 return;
00712             }
00713         }
00714     }
00715 
00716     // Get the LLVM FunctionType
00717     bool disableMask = (storageClass == SC_EXTERN_C);
00718     llvm::FunctionType *llvmFunctionType = 
00719         functionType->LLVMFunctionType(g->ctx, disableMask);
00720     if (llvmFunctionType == NULL)
00721         return;
00722 
00723     // And create the llvm::Function
00724     llvm::GlobalValue::LinkageTypes linkage = (storageClass == SC_STATIC ||
00725                                                isInline) ?
00726         llvm::GlobalValue::InternalLinkage : llvm::GlobalValue::ExternalLinkage;
00727 
00728     std::string functionName = name;
00729     if (storageClass != SC_EXTERN_C) {
00730         functionName += functionType->Mangle();
00731         if (g->mangleFunctionsWithTarget)
00732             functionName += g->target.GetISAString();
00733     }
00734     llvm::Function *function = 
00735         llvm::Function::Create(llvmFunctionType, linkage, functionName.c_str(), 
00736                                module);
00737 
00738     // Set function attributes: we never throw exceptions
00739     function->setDoesNotThrow(true);
00740     if (storageClass != SC_EXTERN_C && 
00741         !g->generateDebuggingSymbols &&
00742         isInline)
00743         function->addFnAttr(llvm::Attribute::AlwaysInline);
00744     if (functionType->isTask)
00745         // This also applies transitively to members I think? 
00746         function->setDoesNotAlias(1, true);
00747 
00748     // Make sure that the return type isn't 'varying' if the function is
00749     // 'export'ed.
00750     if (functionType->isExported && 
00751         lRecursiveCheckValidParamType(functionType->GetReturnType()))
00752         Error(pos, "Illegal to return a \"varying\" type from exported "
00753               "function \"%s\"", name.c_str());
00754 
00755     if (functionType->isTask && 
00756         Type::Equal(functionType->GetReturnType(), AtomicType::Void) == false)
00757         Error(pos, "Task-qualified functions must have void return type.");
00758 
00759     if (functionType->isExported || functionType->isExternC)
00760         lCheckForStructParameters(functionType, pos);
00761 
00762     // Loop over all of the arguments; process default values if present
00763     // and do other checks and parameter attribute setting.
00764     bool seenDefaultArg = false;
00765     int nArgs = functionType->GetNumParameters();
00766     for (int i = 0; i < nArgs; ++i) {
00767         const Type *argType = functionType->GetParameterType(i);
00768         const std::string &argName = functionType->GetParameterName(i);
00769         Expr *defaultValue = functionType->GetParameterDefault(i);
00770         const SourcePos &argPos = functionType->GetParameterSourcePos(i);
00771 
00772         // If the function is exported, make sure that the parameter
00773         // doesn't have any varying stuff going on in it.
00774         if (functionType->isExported)
00775             lCheckForVaryingParameter(argType, argName, argPos);
00776 
00777         // ISPC assumes that no pointers alias.  (It should be possible to
00778         // specify when this is not the case, but this should be the
00779         // default.)  Set parameter attributes accordingly.  (Only for
00780         // uniform pointers, since varying pointers are int vectors...)
00781         if (!functionType->isTask && 
00782             ((CastType<PointerType>(argType) != NULL &&
00783               argType->IsUniformType()) ||
00784              CastType<ReferenceType>(argType) != NULL)) {
00785 
00786             // NOTE: LLVM indexes function parameters starting from 1.
00787             // This is unintuitive.
00788             function->setDoesNotAlias(i+1, true);
00789 #if 0
00790             int align = 4 * RoundUpPow2(g->target.nativeVectorWidth);
00791             function->addAttribute(i+1, llvm::Attribute::constructAlignmentFromInt(align));
00792 #endif
00793         }
00794 
00795         if (symbolTable->LookupFunction(argName.c_str()))
00796             Warning(argPos, "Function parameter \"%s\" shadows a function "
00797                     "declared in global scope.", argName.c_str());
00798         
00799         if (defaultValue != NULL)
00800             seenDefaultArg = true;
00801         else if (seenDefaultArg) {
00802             // Once one parameter has provided a default value, then all of
00803             // the following ones must have them as well.
00804             Error(argPos, "Parameter \"%s\" is missing default: all "
00805                   "parameters after the first parameter with a default value "
00806                   "must have default values as well.", argName.c_str());
00807         }
00808     }
00809 
00810     // If llvm gave us back a Function * with a different name than the one
00811     // we asked for, then there's already a function with that same
00812     // (mangled) name in the llvm::Module.  In that case, erase the one we
00813     // tried to add and just work with the one it already had.
00814     if (function->getName() != functionName) {
00815         function->eraseFromParent();
00816         function = module->getFunction(functionName);
00817     }
00818 
00819     // Finally, we know all is good and we can add the function to the
00820     // symbol table
00821     Symbol *funSym = new Symbol(name, pos, functionType, storageClass);
00822     funSym->function = function;
00823     bool ok = symbolTable->AddFunction(funSym);
00824     Assert(ok);
00825 }
00826 
00827 
00828 void
00829 Module::AddFunctionDefinition(const std::string &name, const FunctionType *type,
00830                               Stmt *code) {
00831     Symbol *sym = symbolTable->LookupFunction(name.c_str(), type);
00832     if (sym == NULL || code == NULL) {
00833         Assert(m->errorCount > 0);
00834         return;
00835     }
00836 
00837     sym->pos = code->pos;
00838 
00839     // FIXME: because we encode the parameter names in the function type,
00840     // we need to override the function type here in case the function had
00841     // earlier been declared with anonymous parameter names but is now
00842     // defined with actual names.  This is yet another reason we shouldn't
00843     // include the names in FunctionType...  
00844     sym->type = type;
00845 
00846     ast->AddFunction(sym, code);
00847 }
00848 
00849 
00850 void
00851 Module::AddExportedTypes(const std::vector<std::pair<const Type *, 
00852                                                      SourcePos> > &types) {
00853     for (int i = 0; i < (int)types.size(); ++i) {
00854         if (CastType<StructType>(types[i].first) == NULL &&
00855             CastType<VectorType>(types[i].first) == NULL &&
00856             CastType<EnumType>(types[i].first) == NULL)
00857             Error(types[i].second, "Only struct, vector, and enum types, "
00858                   "not \"%s\", are allowed in type export lists.", 
00859                   types[i].first->GetString().c_str());
00860         else
00861             exportedTypes.push_back(types[i]);
00862     }
00863 }
00864 
00865 
00866 bool
00867 Module::writeOutput(OutputType outputType, const char *outFileName,
00868                     const char *includeFileName) {
00869     if (diBuilder != NULL && outputType != Header) {
00870         diBuilder->finalize();
00871 
00872         lStripUnusedDebugInfo(module);
00873     }
00874 
00875     // First, issue a warning if the output file suffix and the type of
00876     // file being created seem to mismatch.  This can help catch missing
00877     // command-line arguments specifying the output file type.
00878     const char *suffix = strrchr(outFileName, '.');
00879     if (suffix != NULL) {
00880         ++suffix;
00881         const char *fileType = NULL;
00882         switch (outputType) {
00883         case Asm:
00884             if (strcasecmp(suffix, "s"))
00885                 fileType = "assembly";
00886             break;
00887         case Bitcode:
00888             if (strcasecmp(suffix, "bc"))
00889                 fileType = "LLVM bitcode";
00890             break;
00891         case Object:
00892             if (strcasecmp(suffix, "o") && strcasecmp(suffix, "obj"))
00893                 fileType = "object";
00894             break;
00895         case CXX:
00896             if (strcasecmp(suffix, "c") && strcasecmp(suffix, "cc") &&
00897                 strcasecmp(suffix, "c++") && strcasecmp(suffix, "cxx") &&
00898                 strcasecmp(suffix, "cpp"))
00899                 fileType = "c++";
00900             break;
00901         case Header:
00902             if (strcasecmp(suffix, "h") && strcasecmp(suffix, "hh") &&
00903                 strcasecmp(suffix, "hpp"))
00904                 fileType = "header";
00905             break;
00906         case Deps:
00907           break;
00908         case DevStub:
00909           if (strcasecmp(suffix, "c") && strcasecmp(suffix, "cc") &&
00910               strcasecmp(suffix, "c++") && strcasecmp(suffix, "cxx") &&
00911               strcasecmp(suffix, "cpp"))
00912             fileType = "dev-side offload stub";
00913             break;
00914         case HostStub:
00915           if (strcasecmp(suffix, "c") && strcasecmp(suffix, "cc") &&
00916               strcasecmp(suffix, "c++") && strcasecmp(suffix, "cxx") &&
00917               strcasecmp(suffix, "cpp"))
00918             fileType = "host-side offload stub";
00919             break;
00920         default:
00921           Assert(0 /* swtich case not handled */);
00922           return 1;
00923         }
00924         if (fileType != NULL)
00925             fprintf(stderr, "Warning: emitting %s file, but filename \"%s\" "
00926                     "has suffix \"%s\"?\n", fileType, outFileName, suffix);
00927     }
00928 
00929     if (outputType == Header)
00930       return writeHeader(outFileName);
00931     else if (outputType == Deps)
00932       return writeDeps(outFileName);
00933     else if (outputType == HostStub)
00934       return writeHostStub(outFileName);
00935     else if (outputType == DevStub)
00936       return writeDevStub(outFileName);
00937     else if (outputType == Bitcode)
00938         return writeBitcode(module, outFileName);
00939     else if (outputType == CXX) {
00940         extern bool WriteCXXFile(llvm::Module *module, const char *fn, 
00941                                  int vectorWidth, const char *includeName);
00942         return WriteCXXFile(module, outFileName, g->target.vectorWidth,
00943                             includeFileName);
00944     }
00945     else
00946         return writeObjectFileOrAssembly(outputType, outFileName);
00947 }
00948 
00949 
00950 bool
00951 Module::writeBitcode(llvm::Module *module, const char *outFileName) {
00952     // Get a file descriptor corresponding to where we want the output to
00953     // go.  If we open it, it'll be closed by the llvm::raw_fd_ostream
00954     // destructor.
00955     int fd;
00956     if (!strcmp(outFileName, "-"))
00957         fd = 1; // stdout
00958     else {
00959         int flags = O_CREAT|O_WRONLY|O_TRUNC;
00960 #ifdef ISPC_IS_WINDOWS
00961         flags |= O_BINARY;
00962         fd = _open(outFileName, flags, 0644);
00963 #else
00964         fd = open(outFileName, flags, 0644);
00965 #endif // ISPC_IS_WINDOWS
00966         if (fd == -1) {
00967             perror(outFileName);
00968             return false;
00969         }
00970     }
00971 
00972     llvm::raw_fd_ostream fos(fd, (fd != 1), false);
00973     llvm::WriteBitcodeToFile(module, fos);
00974     return true;
00975 }
00976 
00977 
00978 bool
00979 Module::writeObjectFileOrAssembly(OutputType outputType, const char *outFileName) {
00980     llvm::TargetMachine *targetMachine = g->target.GetTargetMachine();
00981     return writeObjectFileOrAssembly(targetMachine, module, outputType,
00982                                      outFileName);
00983 }
00984 
00985 
00986 bool
00987 Module::writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine,
00988                                   llvm::Module *module, OutputType outputType, 
00989                                   const char *outFileName) {
00990     // Figure out if we're generating object file or assembly output, and
00991     // set binary output for object files
00992     llvm::TargetMachine::CodeGenFileType fileType = (outputType == Object) ? 
00993         llvm::TargetMachine::CGFT_ObjectFile : llvm::TargetMachine::CGFT_AssemblyFile;
00994     bool binary = (fileType == llvm::TargetMachine::CGFT_ObjectFile);
00995     unsigned int flags = binary ? llvm::raw_fd_ostream::F_Binary : 0;
00996 
00997     std::string error;
00998     llvm::tool_output_file *of = new llvm::tool_output_file(outFileName, error, flags);
00999     if (error.size()) {
01000         fprintf(stderr, "Error opening output file \"%s\".\n", outFileName);
01001         return false;
01002     }
01003 
01004     llvm::PassManager pm;
01005     if (const llvm::TargetData *td = targetMachine->getTargetData())
01006         pm.add(new llvm::TargetData(*td));
01007     else
01008         pm.add(new llvm::TargetData(module));
01009 
01010     llvm::formatted_raw_ostream fos(of->os());
01011     llvm::CodeGenOpt::Level optLevel = 
01012         (g->opt.level > 0) ? llvm::CodeGenOpt::Aggressive : llvm::CodeGenOpt::None;
01013 
01014     if (targetMachine->addPassesToEmitFile(pm, fos, fileType, optLevel)) {
01015         fprintf(stderr, "Fatal error adding passes to emit object file!");
01016         exit(1);
01017     }
01018 
01019     // Finally, run the passes to emit the object file/assembly
01020     pm.run(*module);
01021 
01022     // Success; tell tool_output_file to keep the final output file. 
01023     of->keep();
01024 
01025     return true;
01026 }
01027 
01028 
01029 /** Emits a declaration for the given struct to the given file.  This
01030     function first makes sure that declarations for any structs that are
01031     (recursively) members of this struct are emitted first.
01032  */
01033 static void
01034 lEmitStructDecl(const StructType *st, std::vector<const StructType *> *emittedStructs,
01035                 FILE *file) {
01036     // Has this struct type already been declared?  (This happens if it's a
01037     // member of another struct for which we emitted a declaration
01038     // previously.)
01039     for (int i = 0; i < (int)emittedStructs->size(); ++i)
01040         if (Type::EqualIgnoringConst(st, (*emittedStructs)[i]))
01041             return;
01042 
01043     // Otherwise first make sure any contained structs have been declared.
01044     for (int i = 0; i < st->GetElementCount(); ++i) {
01045         const StructType *elementStructType = 
01046             CastType<StructType>(st->GetElementType(i));
01047         if (elementStructType != NULL)
01048             lEmitStructDecl(elementStructType, emittedStructs, file);
01049     }
01050 
01051     // And now it's safe to declare this one
01052     emittedStructs->push_back(st);
01053 
01054     fprintf(file, "struct %s", st->GetStructName().c_str());
01055     if (st->GetSOAWidth() > 0)
01056         // This has to match the naming scheme in
01057         // StructType::GetCDeclaration().
01058         fprintf(file, "_SOA%d", st->GetSOAWidth());
01059     fprintf(file, " {\n");
01060 
01061     for (int i = 0; i < st->GetElementCount(); ++i) {
01062         const Type *type = st->GetElementType(i)->GetAsNonConstType();
01063         std::string d = type->GetCDeclaration(st->GetElementName(i));
01064         fprintf(file, "    %s;\n", d.c_str());
01065     }
01066     fprintf(file, "};\n\n");
01067 }
01068 
01069 
01070 /** Given a set of structures that we want to print C declarations of in a
01071     header file, emit their declarations.
01072  */
01073 static void
01074 lEmitStructDecls(std::vector<const StructType *> &structTypes, FILE *file) {
01075     std::vector<const StructType *> emittedStructs;
01076     for (unsigned int i = 0; i < structTypes.size(); ++i)
01077         lEmitStructDecl(structTypes[i], &emittedStructs, file);
01078     Assert(emittedStructs.size() == structTypes.size());
01079 }
01080 
01081 
01082 /** Emit C declarations of enumerator types to the generated header file.
01083  */
01084 static void
01085 lEmitEnumDecls(const std::vector<const EnumType *> &enumTypes, FILE *file) {
01086     if (enumTypes.size() == 0)
01087         return;
01088 
01089     fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
01090     fprintf(file, "// Enumerator types with external visibility from ispc code\n");
01091     fprintf(file, "///////////////////////////////////////////////////////////////////////////\n\n");
01092     
01093     for (unsigned int i = 0; i < enumTypes.size(); ++i) {
01094         std::string declaration = enumTypes[i]->GetCDeclaration("");
01095         fprintf(file, "%s {\n", declaration.c_str());
01096 
01097         // Print the individual enumerators 
01098         for (int j = 0; j < enumTypes[i]->GetEnumeratorCount(); ++j) {
01099             const Symbol *e = enumTypes[i]->GetEnumerator(j);
01100             Assert(e->constValue != NULL);
01101             unsigned int enumValue;
01102             int count = e->constValue->AsUInt32(&enumValue);
01103             Assert(count == 1);
01104 
01105             // Always print an initializer to set the value.  We could be
01106             // 'clever' here and detect whether the implicit value given by
01107             // one plus the previous enumerator value (or zero, for the
01108             // first enumerator) is the same as the value stored with the
01109             // enumerator, though that doesn't seem worth the trouble...
01110             fprintf(file, "    %s = %d%c\n", e->name.c_str(), enumValue,
01111                     (j < enumTypes[i]->GetEnumeratorCount() - 1) ? ',' : ' ');
01112         }
01113         fprintf(file, "};\n");
01114     }
01115 }
01116 
01117 
01118 /** Print declarations of VectorTypes used in 'export'ed parts of the
01119     program in the header file.
01120  */
01121 static void
01122 lEmitVectorTypedefs(const std::vector<const VectorType *> &types, FILE *file) {
01123     if (types.size() == 0)
01124         return;
01125 
01126     fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
01127     fprintf(file, "// Vector types with external visibility from ispc code\n");
01128     fprintf(file, "///////////////////////////////////////////////////////////////////////////\n\n");
01129 
01130     int align = g->target.nativeVectorWidth * 4;
01131 
01132     for (unsigned int i = 0; i < types.size(); ++i) {
01133         std::string baseDecl;
01134         const VectorType *vt = types[i]->GetAsNonConstType();
01135         if (!vt->IsUniformType())
01136             // Varying stuff shouldn't be visibile to / used by the
01137             // application, so at least make it not simple to access it by
01138             // not declaring the type here...
01139             continue;
01140 
01141         int size = vt->GetElementCount();
01142 
01143         baseDecl = vt->GetBaseType()->GetCDeclaration("");
01144         fprintf(file, "#ifdef _MSC_VER\n__declspec( align(%d) ) ", align);
01145         fprintf(file, "struct %s%d { %s v[%d]; };\n", baseDecl.c_str(), size,
01146                 baseDecl.c_str(), size);
01147         fprintf(file, "#else\n");
01148         fprintf(file, "struct %s%d { %s v[%d]; } __attribute__ ((aligned(%d)));\n", 
01149                 baseDecl.c_str(), size, baseDecl.c_str(), size, align);
01150         fprintf(file, "#endif\n");
01151     }
01152     fprintf(file, "\n");
01153 }
01154 
01155 
01156 /** Add the given type to the vector, if that type isn't already in there.
01157  */
01158 template <typename T> static void
01159 lAddTypeIfNew(const Type *type, std::vector<const T *> *exportedTypes) {
01160     type = type->GetAsNonConstType();
01161 
01162     // Linear search, so this ends up being n^2.  It's unlikely this will
01163     // matter in practice, though.
01164     for (unsigned int i = 0; i < exportedTypes->size(); ++i)
01165         if (Type::Equal((*exportedTypes)[i], type))
01166             return;
01167 
01168     const T *castType = CastType<T>(type);
01169     Assert(castType != NULL);
01170     exportedTypes->push_back(castType);
01171 }
01172 
01173 
01174 /** Given an arbitrary type that appears in the app/ispc interface, add it
01175     to an appropriate vector if it is a struct, enum, or short vector type.
01176     Then, if it's a struct, recursively process its members to do the same.
01177  */
01178 static void
01179 lGetExportedTypes(const Type *type, 
01180                   std::vector<const StructType *> *exportedStructTypes,
01181                   std::vector<const EnumType *> *exportedEnumTypes,
01182                   std::vector<const VectorType *> *exportedVectorTypes) {
01183     const ArrayType *arrayType = CastType<ArrayType>(type);
01184     const StructType *structType = CastType<StructType>(type);
01185 
01186     if (CastType<ReferenceType>(type) != NULL)
01187         lGetExportedTypes(type->GetReferenceTarget(), exportedStructTypes, 
01188                           exportedEnumTypes, exportedVectorTypes);
01189     else if (CastType<PointerType>(type) != NULL)
01190         lGetExportedTypes(type->GetBaseType(), exportedStructTypes,
01191                           exportedEnumTypes, exportedVectorTypes);
01192     else if (arrayType != NULL)
01193         lGetExportedTypes(arrayType->GetElementType(), exportedStructTypes, 
01194                           exportedEnumTypes, exportedVectorTypes);
01195     else if (structType != NULL) {
01196         lAddTypeIfNew(type, exportedStructTypes);
01197         for (int i = 0; i < structType->GetElementCount(); ++i)
01198             lGetExportedTypes(structType->GetElementType(i), exportedStructTypes,
01199                               exportedEnumTypes, exportedVectorTypes);
01200     }
01201     else if (CastType<UndefinedStructType>(type) != NULL)
01202         // do nothing
01203         ;
01204     else if (CastType<EnumType>(type) != NULL)
01205         lAddTypeIfNew(type, exportedEnumTypes);
01206     else if (CastType<VectorType>(type) != NULL)
01207         lAddTypeIfNew(type, exportedVectorTypes);
01208     else
01209         Assert(CastType<AtomicType>(type) != NULL);
01210 }
01211 
01212 
01213 /** Given a set of functions, return the set of structure and vector types
01214     present in the parameters to them.
01215  */
01216 static void
01217 lGetExportedParamTypes(const std::vector<Symbol *> &funcs, 
01218                        std::vector<const StructType *> *exportedStructTypes,
01219                        std::vector<const EnumType *> *exportedEnumTypes,
01220                        std::vector<const VectorType *> *exportedVectorTypes) {
01221     for (unsigned int i = 0; i < funcs.size(); ++i) {
01222         const FunctionType *ftype = CastType<FunctionType>(funcs[i]->type);
01223         // Handle the return type
01224         lGetExportedTypes(ftype->GetReturnType(), exportedStructTypes,
01225                           exportedEnumTypes, exportedVectorTypes);
01226 
01227         // And now the parameter types...
01228         for (int j = 0; j < ftype->GetNumParameters(); ++j)
01229             lGetExportedTypes(ftype->GetParameterType(j), exportedStructTypes,
01230                               exportedEnumTypes, exportedVectorTypes);
01231     }
01232 }
01233 
01234 
01235 static void
01236 lPrintFunctionDeclarations(FILE *file, const std::vector<Symbol *> &funcs,
01237                            bool useExternC=1) {
01238   if (useExternC)
01239     fprintf(file, "#if defined(__cplusplus) && !defined(__ISPC_NO_EXTERN_C)\nextern \"C\" {\n#endif // __cplusplus\n");
01240     // fprintf(file, "#ifdef __cplusplus\nextern \"C\" {\n#endif // __cplusplus\n");
01241   for (unsigned int i = 0; i < funcs.size(); ++i) {
01242     const FunctionType *ftype = CastType<FunctionType>(funcs[i]->type);
01243     Assert(ftype);
01244     std::string decl = ftype->GetCDeclaration(funcs[i]->name);
01245     fprintf(file, "    extern %s;\n", decl.c_str());
01246   }
01247   if (useExternC)
01248 
01249     fprintf(file, "#if defined(__cplusplus) && !defined(__ISPC_NO_EXTERN_C)\n} /* end extern C */\n#endif // __cplusplus\n");
01250     // fprintf(file, "#ifdef __cplusplus\n} /* end extern C */\n#endif // __cplusplus\n");
01251 }
01252 
01253 
01254 
01255 
01256 
01257 
01258 static bool
01259 lIsExported(const Symbol *sym) {
01260     const FunctionType *ft = CastType<FunctionType>(sym->type);
01261     Assert(ft);
01262     return ft->isExported;
01263 }
01264 
01265 
01266 static bool
01267 lIsExternC(const Symbol *sym) {
01268     const FunctionType *ft = CastType<FunctionType>(sym->type);
01269     Assert(ft);
01270     return ft->isExternC;
01271 }
01272 
01273 
01274 bool
01275 Module::writeDeps(const char *fn) {
01276   std::cout << "writing dependencies to file " << fn << std::endl;
01277   FILE *file = fopen(fn,"w");
01278   if (!file) {
01279     perror("fopen");
01280     return false;
01281   }
01282 
01283   for (std::set<std::string>::const_iterator it=registeredDependencies.begin();
01284        it != registeredDependencies.end();
01285        ++it)
01286     fprintf(file,"%s\n",it->c_str());
01287   return true;
01288 }
01289 
01290 
01291 std::string emitOffloadParamStruct(const std::string &paramStructName,
01292                                    const Symbol *sym,
01293                                    const FunctionType *fct)
01294 {
01295   std::stringstream out;
01296   out << "struct " << paramStructName << " {" << std::endl;
01297   
01298   for (int i=0;i<fct->GetNumParameters();i++) {
01299     const Type *orgParamType = fct->GetParameterType(i);
01300     if (orgParamType->IsPointerType() || orgParamType->IsArrayType()) {
01301       /* we're passing pointers separately -- no pointers in that struct... */
01302       continue;
01303     }
01304 
01305     // const reference parameters can be passed as copies.
01306     const Type *paramType;
01307     if (orgParamType->IsReferenceType()) {
01308       if (!orgParamType->IsConstType()) {
01309         Error(sym->pos,"When emitting offload-stubs, \"export\"ed functions cannot have non-const reference-type parameters.\n");
01310       }
01311       const ReferenceType *refType
01312         = dynamic_cast<const ReferenceType*>(orgParamType);
01313       paramType = refType->GetReferenceTarget()->GetAsNonConstType();
01314     } else {
01315       paramType = orgParamType->GetAsNonConstType();
01316     }
01317     std::string paramName = fct->GetParameterName(i);
01318     std::string paramTypeName = paramType->GetString();
01319     
01320     std::string tmpArgDecl = paramType->GetCDeclaration(paramName);
01321     out << "   " << tmpArgDecl << ";" << std::endl;
01322   }
01323 
01324   out << "};" << std::endl;
01325   return out.str();
01326 }
01327 
01328 bool
01329 Module::writeDevStub(const char *fn) 
01330 {
01331   FILE *file = fopen(fn, "w");
01332   if (!file) {
01333     perror("fopen");
01334     return false;
01335   }
01336   fprintf(file, "//\n// %s\n// (device stubs automatically generated by the ispc compiler.)\n", fn);
01337   fprintf(file, "// DO NOT EDIT THIS FILE.\n//\n\n");
01338   fprintf(file,"#include \"ispc/dev/offload.h\"\n\n");
01339 
01340   fprintf(file, "#include <stdint.h>\n\n");
01341   
01342   // Collect single linear arrays of the *exported* functions (we'll
01343   // treat those as "__kernel"s in IVL -- "extern" functions will only
01344   // be used for dev-dev function calls; only "export" functions will
01345   // get exported to the host
01346   std::vector<Symbol *> exportedFuncs;
01347   m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
01348   
01349   // Get all of the struct, vector, and enumerant types used as function
01350   // parameters.  These vectors may have repeats.
01351   std::vector<const StructType *> exportedStructTypes;
01352   std::vector<const EnumType *> exportedEnumTypes;
01353   std::vector<const VectorType *> exportedVectorTypes;
01354   lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
01355                          &exportedEnumTypes, &exportedVectorTypes);
01356   
01357   // And print them
01358   lEmitVectorTypedefs(exportedVectorTypes, file);
01359   lEmitEnumDecls(exportedEnumTypes, file);
01360   lEmitStructDecls(exportedStructTypes, file);
01361   
01362   fprintf(file, "#ifdef __cplusplus\n");
01363   fprintf(file, "namespace ispc {\n");
01364   fprintf(file, "#endif // __cplusplus\n");
01365 
01366   fprintf(file, "\n");
01367   fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
01368   fprintf(file, "// Functions exported from ispc code\n");
01369   fprintf(file, "// (so the dev stub knows what to call)\n");
01370   fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
01371   lPrintFunctionDeclarations(file, exportedFuncs, true);
01372 
01373   fprintf(file, "#ifdef __cplusplus\n");
01374   fprintf(file, "}/* end namespace */\n");
01375   fprintf(file, "#endif // __cplusplus\n");
01376 
01377   fprintf(file, "\n");
01378   fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
01379   fprintf(file, "// actual dev stubs\n");
01380   fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
01381 
01382   fprintf(file, "// note(iw): due to some linking issues offload stubs *only* work under C++\n");
01383   fprintf(file, "extern \"C\" {\n\n");
01384   for (unsigned int i = 0; i < exportedFuncs.size(); ++i) {
01385     const Symbol *sym = exportedFuncs[i];
01386     Assert(sym);
01387     const FunctionType *fct = CastType<FunctionType>(sym->type);
01388     Assert(fct);
01389     
01390     if (!fct->GetReturnType()->IsVoidType()) {
01391       Error(sym->pos,"When emitting offload-stubs, \"export\"ed functions cannot have non-void return types.\n");
01392     }
01393 
01394     // -------------------------------------------------------
01395     // first, emit a struct that holds the parameters
01396     // -------------------------------------------------------
01397     std::string paramStructName = std::string("__ispc_dev_stub_")+sym->name;
01398     std::string paramStruct = emitOffloadParamStruct(paramStructName,sym,fct);
01399     fprintf(file,"%s\n",paramStruct.c_str());
01400     // -------------------------------------------------------
01401     // then, emit a fct stub that unpacks the parameters and pointers
01402     // -------------------------------------------------------
01403     fprintf(file,"void __ispc_dev_stub_%s(\n"
01404             "            uint32_t         in_BufferCount,\n"
01405             "            void**           in_ppBufferPointers,\n"
01406             "            uint64_t*        in_pBufferLengths,\n"
01407             "            void*            in_pMiscData,\n"
01408             "            uint16_t         in_MiscDataLength,\n"
01409             "            void*            in_pReturnValue,\n"
01410             "            uint16_t         in_ReturnValueLength)\n",
01411             sym->name.c_str()
01412             );
01413     fprintf(file,"{\n");
01414     fprintf(file,"  struct %s args;\n  memcpy(&args,in_pMiscData,sizeof(args));\n",
01415             paramStructName.c_str());
01416     std::stringstream funcall;
01417     
01418     funcall << "ispc::" << sym->name << "(";
01419     for (int i=0;i<fct->GetNumParameters();i++) {
01420       // get param type and make it non-const, so we can write while unpacking
01421       // const Type *paramType = fct->GetParameterType(i)->GetAsNonConstType();
01422       const Type *paramType;// = fct->GetParameterType(i)->GetAsNonConstType();
01423       const Type *orgParamType = fct->GetParameterType(i);
01424       if (orgParamType->IsReferenceType()) {
01425         if (!orgParamType->IsConstType()) {
01426           Error(sym->pos,"When emitting offload-stubs, \"export\"ed functions cannot have non-const reference-type parameters.\n");
01427         }
01428         const ReferenceType *refType
01429           = dynamic_cast<const ReferenceType*>(orgParamType);
01430         paramType = refType->GetReferenceTarget()->GetAsNonConstType();
01431       } else {
01432         paramType = orgParamType->GetAsNonConstType();
01433       }
01434       
01435       std::string paramName = fct->GetParameterName(i);
01436       std::string paramTypeName = paramType->GetString();
01437 
01438       if (i) funcall << ", ";
01439       std::string tmpArgName = std::string("_")+paramName;
01440       if (paramType->IsPointerType() || paramType->IsArrayType()) {
01441         std::string tmpArgDecl = paramType->GetCDeclaration(tmpArgName);
01442         fprintf(file,"  %s;\n",
01443                 tmpArgDecl.c_str());
01444         fprintf(file,"  (void *&)%s = ispc_dev_translate_pointer(*in_ppBufferPointers++);\n",
01445                 tmpArgName.c_str());
01446         funcall << tmpArgName;
01447       } else {
01448         funcall << "args." << paramName;
01449       }
01450     }
01451     funcall << ");";
01452     fprintf(file,"  %s\n",funcall.str().c_str());
01453     fprintf(file,"}\n\n");
01454   }
01455 
01456   // end extern "C"
01457   fprintf(file, "}/* end extern C */\n");
01458 
01459   fclose(file);
01460   return true;
01461 }
01462 
01463 
01464 
01465 bool
01466 Module::writeHostStub(const char *fn) 
01467 {
01468   FILE *file = fopen(fn, "w");
01469   if (!file) {
01470     perror("fopen");
01471     return false;
01472   }
01473   fprintf(file, "//\n// %s\n// (device stubs automatically generated by the ispc compiler.)\n", fn);
01474   fprintf(file, "// DO NOT EDIT THIS FILE.\n//\n\n");
01475   fprintf(file,"#include \"ispc/host/offload.h\"\n\n");
01476   fprintf(file,"// note(iw): Host stubs do not get extern C linkage -- dev-side already uses that for the same symbols.\n\n");
01477   //fprintf(file,"#ifdef __cplusplus\nextern \"C\" {\n#endif // __cplusplus\n");
01478 
01479   fprintf(file, "#ifdef __cplusplus\nnamespace ispc {\n#endif // __cplusplus\n\n");
01480   
01481   // Collect single linear arrays of the *exported* functions (we'll
01482   // treat those as "__kernel"s in IVL -- "extern" functions will only
01483   // be used for dev-dev function calls; only "export" functions will
01484   // get exported to the host
01485   std::vector<Symbol *> exportedFuncs;
01486   m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
01487   
01488   // Get all of the struct, vector, and enumerant types used as function
01489   // parameters.  These vectors may have repeats.
01490   std::vector<const StructType *> exportedStructTypes;
01491   std::vector<const EnumType *> exportedEnumTypes;
01492   std::vector<const VectorType *> exportedVectorTypes;
01493   lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
01494                          &exportedEnumTypes, &exportedVectorTypes);
01495   
01496   // And print them
01497   lEmitVectorTypedefs(exportedVectorTypes, file);
01498   lEmitEnumDecls(exportedEnumTypes, file);
01499   lEmitStructDecls(exportedStructTypes, file);
01500   
01501   fprintf(file, "\n");
01502   fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
01503   fprintf(file, "// host-side stubs for dev-side ISPC fucntion(s)\n");
01504   fprintf(file, "///////////////////////////////////////////////////////////////////////////\n");
01505   for (unsigned int i = 0; i < exportedFuncs.size(); ++i) {
01506     const Symbol *sym = exportedFuncs[i];
01507     Assert(sym);
01508     const FunctionType *fct = CastType<FunctionType>(sym->type);
01509     Assert(fct);
01510 
01511     // -------------------------------------------------------
01512     // first, emit a struct that holds the parameters
01513     // -------------------------------------------------------
01514     std::string paramStructName = std::string("__ispc_dev_stub_")+sym->name;
01515     std::string paramStruct = emitOffloadParamStruct(paramStructName,sym,fct);
01516     fprintf(file,"%s\n",paramStruct.c_str());
01517     // -------------------------------------------------------
01518     // then, emit a fct stub that unpacks the parameters and pointers
01519     // -------------------------------------------------------
01520     
01521     std::string decl = fct->GetCDeclaration(sym->name);
01522     fprintf(file, "extern %s {\n", decl.c_str());
01523     int numPointers = 0;
01524     fprintf(file, "  %s __args;\n",paramStructName.c_str());
01525 
01526     // ------------------------------------------------------------------
01527     // write args, and save pointers for later
01528     // ------------------------------------------------------------------
01529     std::stringstream pointerArgs;
01530     for (int i=0;i<fct->GetNumParameters();i++) {
01531       const Type *orgParamType = fct->GetParameterType(i);
01532       std::string paramName = fct->GetParameterName(i);
01533       if (orgParamType->IsPointerType() || orgParamType->IsArrayType()) {
01534         /* we're passing pointers separately -- no pointers in that struct... */
01535         if (numPointers)
01536           pointerArgs << ",";
01537         pointerArgs << "(void*)" << paramName;
01538         numPointers++;
01539         continue;
01540       }
01541 
01542       fprintf(file,"  __args.%s = %s;\n",
01543               paramName.c_str(),paramName.c_str());
01544     }
01545     // ------------------------------------------------------------------
01546     // writer pointer list
01547     // ------------------------------------------------------------------
01548     if (numPointers == 0)
01549       pointerArgs << "NULL";
01550     fprintf(file,"  void *ptr_args[] = { %s };\n" ,pointerArgs.str().c_str());
01551 
01552     // ------------------------------------------------------------------
01553     // ... and call the kernel with those args
01554     // ------------------------------------------------------------------
01555     fprintf(file,"  static ispc_kernel_handle_t kernel_handle = NULL;\n");
01556     fprintf(file,"  if (!kernel_handle) kernel_handle = ispc_host_get_kernel_handle(\"__ispc_dev_stub_%s\");\n",
01557             sym->name.c_str());
01558     fprintf(file,"  assert(kernel_handle);\n");
01559     fprintf(file,
01560             "  ispc_host_call_kernel(kernel_handle,\n"
01561             "                        &__args, sizeof(__args),\n"
01562             "                        ptr_args,%i);\n",
01563             numPointers);
01564     fprintf(file,"}\n\n");
01565   }
01566   
01567   // end extern "C"
01568   fprintf(file, "#ifdef __cplusplus\n");
01569   fprintf(file, "}/* namespace */\n");
01570   fprintf(file, "#endif // __cplusplus\n");
01571   // fprintf(file, "#ifdef __cplusplus\n");
01572   // fprintf(file, "}/* end extern C */\n");
01573   // fprintf(file, "#endif // __cplusplus\n");
01574   
01575   fclose(file);
01576   return true;
01577 }
01578 
01579 
01580 bool
01581 Module::writeHeader(const char *fn) {
01582     FILE *f = fopen(fn, "w");
01583     if (!f) {
01584         perror("fopen");
01585         return false;
01586     }
01587     fprintf(f, "//\n// %s\n// (Header automatically generated by the ispc compiler.)\n", fn);
01588     fprintf(f, "// DO NOT EDIT THIS FILE.\n//\n\n");
01589 
01590     // Create a nice guard string from the filename, turning any
01591     // non-number/letter characters into underbars
01592     std::string guard = "ISPC_";
01593     const char *p = fn;
01594     while (*p) {
01595         if (isdigit(*p)) 
01596             guard += *p;
01597         else if (isalpha(*p)) 
01598             guard += toupper(*p);
01599         else
01600             guard += "_";
01601         ++p;
01602     }
01603     fprintf(f, "#ifndef %s\n#define %s\n\n", guard.c_str(), guard.c_str());
01604 
01605     fprintf(f, "#include <stdint.h>\n\n");
01606 
01607     if (g->emitInstrumentation) {
01608         fprintf(f, "#define ISPC_INSTRUMENTATION 1\n");
01609         fprintf(f, "extern \"C\" {\n");
01610         fprintf(f, "  void ISPCInstrument(const char *fn, const char *note, int line, uint64_t mask);\n");
01611         fprintf(f, "}\n");
01612     }
01613 
01614     // end namespace
01615     fprintf(f, "\n");
01616     fprintf(f, "\n#ifdef __cplusplus\nnamespace ispc { /* namespace */\n#endif // __cplusplus\n");
01617 
01618 
01619     // Collect single linear arrays of the exported and extern "C"
01620     // functions
01621     std::vector<Symbol *> exportedFuncs, externCFuncs;
01622     m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
01623     m->symbolTable->GetMatchingFunctions(lIsExternC, &externCFuncs);
01624     
01625     // Get all of the struct, vector, and enumerant types used as function
01626     // parameters.  These vectors may have repeats.
01627     std::vector<const StructType *> exportedStructTypes;
01628     std::vector<const EnumType *> exportedEnumTypes;
01629     std::vector<const VectorType *> exportedVectorTypes;
01630     lGetExportedParamTypes(exportedFuncs, &exportedStructTypes,
01631                            &exportedEnumTypes, &exportedVectorTypes);
01632     lGetExportedParamTypes(externCFuncs, &exportedStructTypes,
01633                            &exportedEnumTypes, &exportedVectorTypes);
01634 
01635     // Go through the explicitly exported types
01636     for (int i = 0; i < (int)exportedTypes.size(); ++i) {
01637         if (const StructType *st = CastType<StructType>(exportedTypes[i].first))
01638             exportedStructTypes.push_back(st->GetAsUniformType());
01639         else if (const EnumType *et = CastType<EnumType>(exportedTypes[i].first))
01640             exportedEnumTypes.push_back(et->GetAsUniformType());
01641         else if (const VectorType *vt = CastType<VectorType>(exportedTypes[i].first))
01642             exportedVectorTypes.push_back(vt->GetAsUniformType());
01643         else
01644             FATAL("Unexpected type in export list");
01645     }
01646 
01647     // And print them
01648     lEmitVectorTypedefs(exportedVectorTypes, f);
01649     lEmitEnumDecls(exportedEnumTypes, f);
01650     lEmitStructDecls(exportedStructTypes, f);
01651 
01652     // emit function declarations for exported stuff...
01653     if (exportedFuncs.size() > 0) {
01654         fprintf(f, "\n");
01655         fprintf(f, "///////////////////////////////////////////////////////////////////////////\n");
01656         fprintf(f, "// Functions exported from ispc code\n");
01657         fprintf(f, "///////////////////////////////////////////////////////////////////////////\n");
01658         lPrintFunctionDeclarations(f, exportedFuncs);
01659     }
01660 #if 0
01661     if (externCFuncs.size() > 0) {
01662         fprintf(f, "\n");
01663         fprintf(f, "///////////////////////////////////////////////////////////////////////////\n");
01664         fprintf(f, "// External C functions used by ispc code\n");
01665         fprintf(f, "///////////////////////////////////////////////////////////////////////////\n");
01666         lPrintFunctionDeclarations(f, externCFuncs);
01667     }
01668 #endif
01669 
01670     // end namespace
01671     fprintf(f, "\n");
01672     fprintf(f, "\n#ifdef __cplusplus\n} /* namespace */\n#endif // __cplusplus\n");
01673 
01674     // end guard
01675     fprintf(f, "\n#endif // %s\n", guard.c_str());
01676 
01677     fclose(f);
01678     return true;
01679 }
01680 
01681 
01682 void
01683 Module::execPreprocessor(const char* infilename, llvm::raw_string_ostream* ostream) const
01684 {
01685     clang::CompilerInstance inst;
01686     inst.createFileManager();
01687 
01688     llvm::raw_fd_ostream stderrRaw(2, false);
01689 
01690     clang::TextDiagnosticPrinter *diagPrinter =
01691         new clang::TextDiagnosticPrinter(stderrRaw, clang::DiagnosticOptions());
01692     llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs(new clang::DiagnosticIDs);
01693     clang::DiagnosticsEngine *diagEngine = 
01694         new clang::DiagnosticsEngine(diagIDs, diagPrinter);
01695     inst.setDiagnostics(diagEngine);
01696 
01697     clang::TargetOptions &options = inst.getTargetOpts();
01698     llvm::Triple triple(module->getTargetTriple());
01699     if (triple.getTriple().empty()) {
01700 #ifdef LLVM_3_0
01701         triple.setTriple(llvm::sys::getHostTriple());
01702 #else
01703         triple.setTriple(llvm::sys::getDefaultTargetTriple());
01704 #endif
01705     }
01706     options.Triple = triple.getTriple();
01707 
01708     clang::TargetInfo *target =
01709         clang::TargetInfo::CreateTargetInfo(inst.getDiagnostics(), options);
01710 
01711     inst.setTarget(target);
01712     inst.createSourceManager(inst.getFileManager());
01713     inst.InitializeSourceManager(infilename);
01714 
01715     // Don't remove comments in the preprocessor, so that we can accurately
01716     // track the source file position by handling them ourselves.
01717     inst.getPreprocessorOutputOpts().ShowComments = 1;
01718 
01719     clang::HeaderSearchOptions &headerOpts = inst.getHeaderSearchOpts();
01720     headerOpts.UseBuiltinIncludes = 0;
01721     headerOpts.UseStandardSystemIncludes = 0;
01722     headerOpts.UseStandardCXXIncludes = 0;
01723     if (g->debugPrint)
01724         headerOpts.Verbose = 1;
01725     for (int i = 0; i < (int)g->includePath.size(); ++i)
01726         headerOpts.AddPath(g->includePath[i], clang::frontend::Angled,
01727                            true /* is user supplied */,
01728                            false /* not a framework */,
01729                            true /* ignore sys root */);
01730 
01731     clang::PreprocessorOptions &opts = inst.getPreprocessorOpts();
01732 
01733     // Add defs for ISPC and PI
01734     opts.addMacroDef("ISPC");
01735     opts.addMacroDef("PI=3.1415926535");
01736 
01737     // Add #define for current compilation target
01738     char targetMacro[128];
01739     sprintf(targetMacro, "ISPC_TARGET_%s", g->target.GetISAString());
01740     char *p = targetMacro;
01741     while (*p) {
01742         *p = toupper(*p);
01743         ++p;
01744     }
01745     opts.addMacroDef(targetMacro);
01746 
01747     if (g->target.is32Bit)
01748         opts.addMacroDef("ISPC_POINTER_SIZE=32");
01749     else
01750         opts.addMacroDef("ISPC_POINTER_SIZE=64");
01751 
01752     if (g->target.hasHalf)
01753         opts.addMacroDef("ISPC_TARGET_HAS_HALF");
01754     if (g->target.hasTranscendentals)
01755         opts.addMacroDef("ISPC_TARGET_HAS_TRANSCENDENTALS");
01756 
01757     opts.addMacroDef("ISPC_MAJOR_VERSION=1");
01758     opts.addMacroDef("ISPC_MINOR_VERSION=3");
01759 
01760     if (g->includeStdlib) {
01761         if (g->opt.disableAsserts) 
01762             opts.addMacroDef("assert(x)=");
01763         else
01764             opts.addMacroDef("assert(x)=__assert(#x, x)");
01765     }
01766 
01767     for (unsigned int i = 0; i < g->cppArgs.size(); ++i) {
01768         // Sanity check--should really begin with -D
01769         if (g->cppArgs[i].substr(0,2) == "-D") {
01770             opts.addMacroDef(g->cppArgs[i].substr(2));
01771         }
01772     }    
01773     inst.createPreprocessor();
01774 
01775     clang::LangOptions langOptions;
01776     diagPrinter->BeginSourceFile(langOptions, &inst.getPreprocessor());
01777     clang::DoPrintPreprocessedInput(inst.getPreprocessor(),
01778                                     ostream, inst.getPreprocessorOutputOpts());
01779     diagPrinter->EndSourceFile();
01780 }
01781 
01782 
01783 // Given an output filename of the form "foo.obj", and an ISA name like
01784 // "avx", return a string with the ISA name inserted before the original
01785 // filename's suffix, like "foo_avx.obj".
01786 static std::string
01787 lGetTargetFileName(const char *outFileName, const char *isaString) {
01788     char *targetOutFileName = new char[strlen(outFileName) + 16];
01789     if (strrchr(outFileName, '.') != NULL) {
01790         // Copy everything up to the last '.'
01791         int count = strrchr(outFileName, '.') - outFileName;
01792         strncpy(targetOutFileName, outFileName, count);
01793         targetOutFileName[count] = '\0';
01794 
01795         // Add the ISA name
01796         strcat(targetOutFileName, "_");
01797         strcat(targetOutFileName, isaString);
01798 
01799         // And finish with the original file suffiz
01800         strcat(targetOutFileName, strrchr(outFileName, '.'));
01801     }
01802     else {
01803         // Can't find a '.' in the filename, so just append the ISA suffix
01804         // to what we weregiven
01805         strcpy(targetOutFileName, outFileName);
01806         strcat(targetOutFileName, "_");
01807         strcat(targetOutFileName, isaString);
01808     }
01809     return targetOutFileName;
01810 }
01811 
01812 
01813 // Given a comma-delimited string with one or more compilation targets of
01814 // the form "sse2,avx-x2", return a vector of strings where each returned
01815 // string holds one of the targets from the given string.
01816 static std::vector<std::string> 
01817 lExtractTargets(const char *target) {
01818     std::vector<std::string> targets;
01819     const char *tstart = target;
01820     bool done = false;
01821     while (!done) {
01822         const char *tend = strchr(tstart, ',');
01823         if (tend == NULL) {
01824             done = true;
01825             tend = strchr(tstart, '\0');
01826         }
01827         targets.push_back(std::string(tstart, tend));
01828         tstart = tend+1;
01829     }
01830     return targets;
01831 }
01832 
01833 
01834 static bool
01835 lSymbolIsExported(const Symbol *s) {
01836     return s->exportedFunction != NULL;
01837 }
01838 
01839 
01840 // Small structure to hold pointers to the various different versions of a
01841 // llvm::Function that were compiled for different compilation target ISAs.
01842 struct FunctionTargetVariants {
01843     FunctionTargetVariants() {
01844         for (int i = 0; i < Target::NUM_ISAS; ++i)
01845             func[i] = NULL;
01846     }
01847     // The func array is indexed with the Target::ISA enumerant.  Some
01848     // values may be NULL, indicating that the original function wasn't
01849     // compiled to the corresponding target ISA.
01850     llvm::Function *func[Target::NUM_ISAS];
01851 };
01852 
01853 
01854 // Given the symbol table for a module, return a map from function names to
01855 // FunctionTargetVariants for each function that was defined with the
01856 // 'export' qualifier in ispc.
01857 static void 
01858 lGetExportedFunctions(SymbolTable *symbolTable, 
01859                       std::map<std::string, FunctionTargetVariants> &functions) {
01860     std::vector<Symbol *> syms;
01861     symbolTable->GetMatchingFunctions(lSymbolIsExported, &syms);
01862     for (unsigned int i = 0; i < syms.size(); ++i) {
01863         FunctionTargetVariants &ftv = functions[syms[i]->name];
01864         ftv.func[g->target.isa] = syms[i]->exportedFunction;    
01865     }
01866 }
01867 
01868 
01869 struct RewriteGlobalInfo {
01870     RewriteGlobalInfo(llvm::GlobalVariable *g = NULL, llvm::Constant *i = NULL,
01871                       SourcePos p = SourcePos()) {
01872         gv = g;
01873         init = i;
01874         pos = p;
01875     }
01876 
01877     llvm::GlobalVariable *gv;
01878     llvm::Constant *init;
01879     SourcePos pos;
01880 };
01881 
01882 // Grab all of the global value definitions from the module and change them
01883 // to be declarations; we'll emit a single definition of each global in the
01884 // final module used with the dispatch functions, so that we don't have
01885 // multiple definitions of them, one in each of the target-specific output
01886 // files.
01887 static void
01888 lExtractAndRewriteGlobals(llvm::Module *module, 
01889                           std::vector<RewriteGlobalInfo> *globals) {
01890     llvm::Module::global_iterator iter;
01891     for (iter = module->global_begin(); iter != module->global_end(); ++iter) {
01892         llvm::GlobalVariable *gv = iter;
01893         // Is it a global definition?
01894         if (gv->getLinkage() == llvm::GlobalValue::ExternalLinkage &&
01895             gv->hasInitializer()) {
01896             // Turn this into an 'extern 'declaration by clearing its
01897             // initializer.
01898             llvm::Constant *init = gv->getInitializer();
01899             gv->setInitializer(NULL);
01900 
01901             Symbol *sym = 
01902                 m->symbolTable->LookupVariable(gv->getName().str().c_str());
01903             Assert(sym != NULL);
01904             globals->push_back(RewriteGlobalInfo(gv, init, sym->pos));
01905         }
01906     }
01907 }
01908 
01909 
01910 // This function emits a global variable definition for each global that
01911 // was turned into a declaration in the target-specific output file.
01912 static void
01913 lAddExtractedGlobals(llvm::Module *module,
01914                      std::vector<RewriteGlobalInfo> globals[Target::NUM_ISAS]) {
01915     // Find the first element in the globals[] array that has values stored
01916     // in it.  All elements of this array should either have empty vectors
01917     // (if we didn't compile to the corresponding ISA or if there are no
01918     // globals), or should have the same number of vector elements as the
01919     // other non-empty vectors.
01920     int firstActive = -1;
01921     for (int i = 0; i < Target::NUM_ISAS; ++i)
01922         if (globals[i].size() > 0) {
01923             firstActive = i;
01924             break;
01925         }
01926 
01927     if (firstActive == -1)
01928         // no globals
01929         return;
01930 
01931     for (unsigned int i = 0; i < globals[firstActive].size(); ++i) {
01932         RewriteGlobalInfo &rgi = globals[firstActive][i];
01933         llvm::GlobalVariable *gv = rgi.gv;
01934         llvm::Type *type = gv->getType()->getElementType();
01935         llvm::Constant *initializer = rgi.init;
01936 
01937         // Create a new global in the given model that matches the original
01938         // global
01939         llvm::GlobalVariable *newGlobal = 
01940             new llvm::GlobalVariable(*module, type, gv->isConstant(),
01941                                      llvm::GlobalValue::ExternalLinkage,
01942                                      initializer, gv->getName());
01943         newGlobal->copyAttributesFrom(gv);
01944 
01945         // For all of the other targets that we actually generated code
01946         // for, make sure the global we just created is compatible with the
01947         // global from the module for that target.
01948         for (int j = firstActive + 1; j < Target::NUM_ISAS; ++j) {
01949             if (globals[j].size() > 0) {
01950                 // There should be the same number of globals in the other
01951                 // vectors, in the same order.
01952                 Assert(globals[firstActive].size() == globals[j].size());
01953                 llvm::GlobalVariable *gv2 = globals[j][i].gv;
01954                 Assert(gv2->getName() == gv->getName());
01955 
01956                 // It is possible that the types may not match, though--for
01957                 // example, this happens with varying globals if we compile
01958                 // to different vector widths.
01959                 if (gv2->getType() != gv->getType())
01960                     Error(rgi.pos, "Mismatch in size/layout of global "
01961                           "variable \"%s\" with different targets. "
01962                           "Globals must not include \"varying\" types or arrays "
01963                           "with size based on programCount when compiling to "
01964                           "targets with differing vector widths.",
01965                           gv->getName().str().c_str());
01966             }
01967         }
01968     }
01969 }
01970 
01971 
01972 /** Create the dispatch function for an exported ispc function.
01973     This function checks to see which vector ISAs the system the 
01974     code is running on supports and calls out to the best available
01975     variant that was generated at compile time.
01976 
01977     @param module      Module in which to create the dispatch function.
01978     @param setISAFunc  Pointer to the __set_system_isa() function defined
01979                        in builtins-dispatch.ll (which is linked into the
01980                        given module before we get here.)
01981     @param systemBestISAPtr  Pointer to the module-local __system_best_isa
01982                              variable, which holds a value of the Target::ISA
01983                              enumerant giving the most capable ISA that the
01984                              system supports.
01985     @param name        Name of the function for which we're generating a
01986                        dispatch function
01987     @param funcs       Target-specific variants of the exported function.
01988 */
01989 static void
01990 lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISAFunc,
01991                         llvm::Value *systemBestISAPtr, const std::string &name, 
01992                         FunctionTargetVariants &funcs) {
01993     // The llvm::Function pointers in funcs are pointers to functions in
01994     // different llvm::Modules, so we can't call them directly.  Therefore,
01995     // we'll start by generating an 'extern' declaration of each one that
01996     // we have in the current module so that we can then call out to that.
01997     llvm::Function *targetFuncs[Target::NUM_ISAS];
01998     llvm::FunctionType *ftype = NULL;
01999 
02000     for (int i = 0; i < Target::NUM_ISAS; ++i) {
02001         if (funcs.func[i] == NULL) {
02002             targetFuncs[i] = NULL;
02003             continue;
02004         }
02005 
02006         // Grab the type of the function as well.  Note that the various
02007         // functions will have different types if they have arguments that
02008         // are pointers to structs, due to the fact that we mangle LLVM
02009         // struct type names with the target vector width.  However,
02010         // because we only allow uniform stuff to pass through the
02011         // export'ed function layer, they should all have the same memory
02012         // layout, so this is benign..
02013         if (ftype == NULL)
02014             ftype = funcs.func[i]->getFunctionType();
02015 
02016         targetFuncs[i] = 
02017             llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage, 
02018                                    funcs.func[i]->getName(), module);
02019     }
02020 
02021     bool voidReturn = ftype->getReturnType()->isVoidTy();
02022 
02023     // Now we can emit the definition of the dispatch function..
02024     llvm::Function *dispatchFunc = 
02025         llvm::Function::Create(ftype, llvm::GlobalValue::ExternalLinkage, 
02026                                name.c_str(), module);
02027     llvm::BasicBlock *bblock = 
02028         llvm::BasicBlock::Create(*g->ctx, "entry", dispatchFunc);
02029 
02030     // Start by calling out to the function that determines the system's
02031     // ISA and sets __system_best_isa, if it hasn't been set yet.
02032     llvm::CallInst::Create(setISAFunc, "", bblock);
02033 
02034     // Now we can load the system's ISA enuemrant
02035     llvm::Value *systemISA = 
02036         new llvm::LoadInst(systemBestISAPtr, "system_isa", bblock);
02037 
02038     // Now emit code that works backwards though the available variants of
02039     // the function.  We'll call out to the first one we find that will run
02040     // successfully on the system the code is running on.  In working
02041     // through the candidate ISAs here backward, we're taking advantage of
02042     // the expectation that they are ordered in the Target::ISA enumerant
02043     // from least to most capable.
02044     for (int i = Target::NUM_ISAS-1; i >= 0; --i) {
02045         if (targetFuncs[i] == NULL)
02046             continue;
02047 
02048         // Emit code to see if the system can run the current candidate
02049         // variant successfully--"is the system's ISA enuemrant value >=
02050         // the enumerant value of the current candidate?"
02051         llvm::Value *ok = 
02052             llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGE,
02053                                   systemISA, LLVMInt32(i), "isa_ok", bblock);
02054         llvm::BasicBlock *callBBlock = 
02055             llvm::BasicBlock::Create(*g->ctx, "do_call", dispatchFunc);
02056         llvm::BasicBlock *nextBBlock = 
02057             llvm::BasicBlock::Create(*g->ctx, "next_try", dispatchFunc);
02058         llvm::BranchInst::Create(callBBlock, nextBBlock, ok, bblock);
02059 
02060         // Emit the code to make the call call in callBBlock.
02061         // Just pass through all of the args from the dispatch function to
02062         // the target-specific function.
02063         std::vector<llvm::Value *> args;
02064         llvm::Function::arg_iterator argIter = dispatchFunc->arg_begin(); 
02065         for (; argIter != dispatchFunc->arg_end(); ++argIter)
02066             args.push_back(argIter);
02067         if (voidReturn) {
02068             llvm::CallInst::Create(targetFuncs[i], args, "", callBBlock);
02069             llvm::ReturnInst::Create(*g->ctx, callBBlock);
02070         }
02071         else {
02072             llvm::Value *retValue = 
02073                 llvm::CallInst::Create(targetFuncs[i], args, "ret_value", 
02074                                        callBBlock);
02075             llvm::ReturnInst::Create(*g->ctx, retValue, callBBlock);
02076         }
02077 
02078         // Otherwise we'll go on to the next candidate and see about that
02079         // one...
02080         bblock = nextBBlock;
02081     }
02082 
02083     // We couldn't find a match that the current system was capable of
02084     // running.  We'll call abort(); this is a bit of a blunt hammer--it
02085     // might be preferable to call a user-supplied callback--ISPCError(...)
02086     // or some such, but we don't want to start imposing too much of a
02087     // runtime library requirement either...
02088     llvm::Function *abortFunc = module->getFunction("abort");
02089     Assert(abortFunc);
02090     llvm::CallInst::Create(abortFunc, "", bblock);
02091 
02092     // Return an undef value from the function here; we won't get to this
02093     // point at runtime, but LLVM needs all of the basic blocks to be
02094     // terminated...
02095     if (voidReturn)
02096         llvm::ReturnInst::Create(*g->ctx, bblock);
02097     else {
02098         llvm::Value *undefRet = llvm::UndefValue::get(ftype->getReturnType());
02099         llvm::ReturnInst::Create(*g->ctx, undefRet, bblock);
02100     }
02101 }
02102 
02103 
02104 // Given a map that holds the mapping from each of the 'export'ed functions
02105 // in the ispc program to the target-specific variants of the function,
02106 // create a llvm::Module that has a dispatch function for each exported
02107 // function that checks the system's capabilities and picks the most
02108 // appropriate compiled variant of the function.
02109 static llvm::Module *
02110 lCreateDispatchModule(std::map<std::string, FunctionTargetVariants> &functions) {
02111     llvm::Module *module = new llvm::Module("dispatch_module", *g->ctx);
02112 
02113     // First, link in the definitions from the builtins-dispatch.ll file.
02114     extern unsigned char builtins_bitcode_dispatch[];
02115     extern int builtins_bitcode_dispatch_length;
02116     AddBitcodeToModule(builtins_bitcode_dispatch, 
02117                        builtins_bitcode_dispatch_length, module);
02118 
02119     // Get pointers to things we need below
02120     llvm::Function *setFunc = module->getFunction("__set_system_isa");
02121     Assert(setFunc != NULL);
02122     llvm::Value *systemBestISAPtr = 
02123         module->getGlobalVariable("__system_best_isa", true);
02124     Assert(systemBestISAPtr != NULL);
02125 
02126     // For each exported function, create the dispatch function
02127     std::map<std::string, FunctionTargetVariants>::iterator iter;
02128     for (iter = functions.begin(); iter != functions.end(); ++iter)
02129         lCreateDispatchFunction(module, setFunc, systemBestISAPtr,
02130                                 iter->first, iter->second);
02131 
02132     // Do some rudimentary cleanup of the final result and make sure that
02133     // the module is all ok.
02134     llvm::PassManager optPM;
02135     optPM.add(llvm::createGlobalDCEPass());
02136     optPM.add(llvm::createVerifierPass());
02137     optPM.run(*module);
02138 
02139     return module;
02140 }
02141 
02142 
02143 int
02144 Module::CompileAndOutput(const char *srcFile, 
02145                          const char *arch, 
02146                          const char *cpu, 
02147                          const char *target, 
02148                          bool generatePIC, 
02149                          OutputType outputType, 
02150                          const char *outFileName, 
02151                          const char *headerFileName,
02152                          const char *includeFileName,
02153                          const char *depsFileName,
02154                          const char *hostStubFileName,
02155                          const char *devStubFileName) 
02156 {
02157     if (target == NULL || strchr(target, ',') == NULL) {
02158         // We're only compiling to a single target
02159         if (!Target::GetTarget(arch, cpu, target, generatePIC, &g->target))
02160             return 1;
02161 
02162         m = new Module(srcFile);
02163         if (m->CompileFile() == 0) {
02164             if (outFileName != NULL)
02165                 if (!m->writeOutput(outputType, outFileName, includeFileName))
02166                     return 1;
02167             if (headerFileName != NULL)
02168                 if (!m->writeOutput(Module::Header, headerFileName))
02169                     return 1;
02170             if (depsFileName != NULL)
02171               if (!m->writeOutput(Module::Deps,depsFileName))
02172                 return 1;
02173             if (hostStubFileName != NULL)
02174               if (!m->writeOutput(Module::HostStub,hostStubFileName))
02175                 return 1;
02176             if (devStubFileName != NULL)
02177               if (!m->writeOutput(Module::DevStub,devStubFileName))
02178                 return 1;
02179         }
02180         else
02181             ++m->errorCount;
02182 
02183         int errorCount = m->errorCount;
02184         delete m;
02185         m = NULL;
02186 
02187         return errorCount > 0;
02188     }
02189     else {
02190         if (outputType == CXX) {
02191             Error(SourcePos(), "Illegal to specify more then one target when "
02192                   "compiling C++ output.");
02193             return 1;
02194         }
02195 
02196         // The user supplied multiple targets
02197         std::vector<std::string> targets = lExtractTargets(target);
02198         Assert(targets.size() > 1);
02199 
02200         if (outFileName != NULL && strcmp(outFileName, "-") == 0) {
02201             Error(SourcePos(), "Multi-target compilation can't generate output "
02202                   "to stdout.  Please provide an output filename.\n");
02203             return 1;
02204         }
02205 
02206         // Make sure that the function names for 'export'ed functions have
02207         // the target ISA appended to them.
02208         g->mangleFunctionsWithTarget = true;
02209 
02210         llvm::TargetMachine *targetMachines[Target::NUM_ISAS];
02211         for (int i = 0; i < Target::NUM_ISAS; ++i)
02212             targetMachines[i] = NULL;
02213 
02214         std::map<std::string, FunctionTargetVariants> exportedFunctions;
02215         std::vector<RewriteGlobalInfo> globals[Target::NUM_ISAS];
02216         int errorCount = 0;
02217         for (unsigned int i = 0; i < targets.size(); ++i) {
02218             if (!Target::GetTarget(arch, cpu, targets[i].c_str(), generatePIC, 
02219                                    &g->target))
02220                 return 1;
02221 
02222             // Issue an error if we've already compiled to a variant of
02223             // this target ISA.  (It doesn't make sense to compile to both
02224             // avx and avx-x2, for example.)
02225             if (targetMachines[g->target.isa] != NULL) {
02226                 Error(SourcePos(), "Can't compile to multiple variants of %s "
02227                       "target!\n", g->target.GetISAString());
02228                 return 1;
02229             }
02230             targetMachines[g->target.isa] = g->target.GetTargetMachine();
02231 
02232             m = new Module(srcFile);
02233             if (m->CompileFile() == 0) {
02234                 // Grab pointers to the exported functions from the module we
02235                 // just compiled, for use in generating the dispatch function
02236                 // later.
02237                 lGetExportedFunctions(m->symbolTable, exportedFunctions);
02238 
02239                 lExtractAndRewriteGlobals(m->module, &globals[i]);
02240 
02241                 if (outFileName != NULL) {
02242                     const char *isaName = g->target.GetISAString();
02243                     std::string targetOutFileName = 
02244                         lGetTargetFileName(outFileName, isaName);
02245                     if (!m->writeOutput(outputType, targetOutFileName.c_str()))
02246                         return 1;
02247                 }
02248             }
02249             errorCount += m->errorCount;
02250 
02251             // Only write the generate header file, if desired, the first
02252             // time through the loop here.
02253             if (i == 0 && headerFileName != NULL)
02254                 if (!m->writeOutput(Module::Header, headerFileName))
02255                     return 1;
02256 
02257             // Important: Don't delete the llvm::Module *m here; we need to
02258             // keep it around so the llvm::Functions *s stay valid for when
02259             // we generate the dispatch module's functions...
02260         }
02261 
02262         llvm::Module *dispatchModule = 
02263             lCreateDispatchModule(exportedFunctions);
02264 
02265         lAddExtractedGlobals(dispatchModule, globals);
02266 
02267         // Find the first non-NULL target machine from the targets we
02268         // compiled to above.  We'll use this as the target machine for
02269         // compiling the dispatch module--this is safe in that it is the
02270         // least-common-denominator of all of the targets we compiled to.
02271         llvm::TargetMachine *firstTargetMachine = targetMachines[0];
02272         int i = 1;
02273         while (i < Target::NUM_ISAS && firstTargetMachine == NULL)
02274             firstTargetMachine = targetMachines[i++];
02275         Assert(firstTargetMachine != NULL);
02276 
02277         if (outFileName != NULL) {
02278             if (outputType == Bitcode)
02279                 writeBitcode(dispatchModule, outFileName);
02280             else
02281                 writeObjectFileOrAssembly(firstTargetMachine, dispatchModule,
02282                                           outputType, outFileName);
02283         }
02284         
02285         return errorCount > 0;
02286     }
02287 }