|
Intel SPMD Program Compiler
1.3.0
|
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 ispc.cpp 00035 @brief ispc global definitions 00036 */ 00037 00038 #include "ispc.h" 00039 #include "module.h" 00040 #include "util.h" 00041 #include "llvmutil.h" 00042 #include <stdio.h> 00043 #ifdef ISPC_IS_WINDOWS 00044 #include <windows.h> 00045 #include <direct.h> 00046 #define strcasecmp stricmp 00047 #endif 00048 #include <llvm/LLVMContext.h> 00049 #include <llvm/Module.h> 00050 #include <llvm/Analysis/DIBuilder.h> 00051 #if defined(LLVM_3_0) || defined(LLVM_3_1) 00052 #include <llvm/Analysis/DebugInfo.h> 00053 #else 00054 #include <llvm/DebugInfo.h> 00055 #endif 00056 #include <llvm/Support/Dwarf.h> 00057 #include <llvm/Instructions.h> 00058 #include <llvm/Target/TargetMachine.h> 00059 #include <llvm/Target/TargetOptions.h> 00060 #include <llvm/Target/TargetData.h> 00061 #include <llvm/Support/TargetRegistry.h> 00062 #include <llvm/Support/TargetSelect.h> 00063 #include <llvm/Support/Host.h> 00064 00065 Globals *g; 00066 Module *m; 00067 00068 /////////////////////////////////////////////////////////////////////////// 00069 // Target 00070 00071 #ifndef ISPC_IS_WINDOWS 00072 static void __cpuid(int info[4], int infoType) { 00073 __asm__ __volatile__ ("cpuid" 00074 : "=a" (info[0]), "=b" (info[1]), "=c" (info[2]), "=d" (info[3]) 00075 : "0" (infoType)); 00076 } 00077 00078 /* Save %ebx in case it's the PIC register */ 00079 static void __cpuidex(int info[4], int level, int count) { 00080 __asm__ __volatile__ ("xchg{l}\t{%%}ebx, %1\n\t" 00081 "cpuid\n\t" 00082 "xchg{l}\t{%%}ebx, %1\n\t" 00083 : "=a" (info[0]), "=r" (info[1]), "=c" (info[2]), "=d" (info[3]) 00084 : "0" (level), "2" (count)); 00085 } 00086 #endif // ISPC_IS_WINDOWS 00087 00088 00089 static const char * 00090 lGetSystemISA() { 00091 int info[4]; 00092 __cpuid(info, 1); 00093 00094 if ((info[2] & (1 << 28)) != 0) { 00095 // AVX1 for sure. Do we have AVX2? 00096 // Call cpuid with eax=7, ecx=0 00097 __cpuidex(info, 7, 0); 00098 if ((info[1] & (1 << 5)) != 0) 00099 return "avx2"; 00100 else { 00101 // ivybridge? 00102 if ((info[2] & (1 << 29)) != 0 && // F16C 00103 (info[2] & (1 << 30)) != 0) // RDRAND 00104 return "avx1.1"; 00105 else 00106 return "avx"; 00107 } 00108 } 00109 else if ((info[2] & (1 << 19)) != 0) 00110 return "sse4"; 00111 else if ((info[3] & (1 << 26)) != 0) 00112 return "sse2"; 00113 else { 00114 fprintf(stderr, "Unable to detect supported SSE/AVX ISA. Exiting.\n"); 00115 exit(1); 00116 } 00117 } 00118 00119 00120 static const char *supportedCPUs[] = { 00121 "atom", "penryn", "core2", "corei7", "corei7-avx" 00122 }; 00123 00124 00125 bool 00126 Target::GetTarget(const char *arch, const char *cpu, const char *isa, 00127 bool pic, Target *t) { 00128 if (isa == NULL) { 00129 if (cpu != NULL) { 00130 // If a CPU was specified explicitly, try to pick the best 00131 // possible ISA based on that. 00132 if (!strcmp(cpu, "sandybridge") || 00133 !strcmp(cpu, "corei7-avx")) 00134 isa = "avx"; 00135 else if (!strcmp(cpu, "corei7") || 00136 !strcmp(cpu, "penryn")) 00137 isa = "sse4"; 00138 else 00139 isa = "sse2"; 00140 fprintf(stderr, "Notice: no --target specified on command-line. " 00141 "Using ISA \"%s\" based on specified CPU \"%s\".\n", isa, 00142 cpu); 00143 } 00144 else { 00145 // No CPU and no ISA, so use CPUID to figure out what this CPU 00146 // supports. 00147 isa = lGetSystemISA(); 00148 fprintf(stderr, "Notice: no --target specified on command-line. " 00149 "Using system ISA \"%s\".\n", isa); 00150 } 00151 } 00152 00153 if (cpu == NULL) { 00154 std::string hostCPU = llvm::sys::getHostCPUName(); 00155 if (hostCPU.size() > 0) 00156 cpu = strdup(hostCPU.c_str()); 00157 else { 00158 fprintf(stderr, "Warning: unable to determine host CPU!\n"); 00159 cpu = "generic"; 00160 } 00161 } 00162 else { 00163 bool foundCPU = false; 00164 for (int i = 0; i < int(sizeof(supportedCPUs) / sizeof(supportedCPUs[0])); 00165 ++i) { 00166 if (!strcmp(cpu, supportedCPUs[i])) { 00167 foundCPU = true; 00168 break; 00169 } 00170 } 00171 if (foundCPU == false) { 00172 fprintf(stderr, "Error: CPU type \"%s\" unknown. Supported CPUs: " 00173 "%s.\n", cpu, SupportedTargetCPUs().c_str()); 00174 return false; 00175 } 00176 } 00177 00178 t->cpu = cpu; 00179 00180 if (arch == NULL) 00181 arch = "x86-64"; 00182 00183 bool error = false; 00184 00185 t->generatePIC = pic; 00186 00187 // Make sure the target architecture is a known one; print an error 00188 // with the valid ones otherwise. 00189 t->target = NULL; 00190 for (llvm::TargetRegistry::iterator iter = llvm::TargetRegistry::begin(); 00191 iter != llvm::TargetRegistry::end(); ++iter) { 00192 if (std::string(arch) == iter->getName()) { 00193 t->target = &*iter; 00194 break; 00195 } 00196 } 00197 if (t->target == NULL) { 00198 fprintf(stderr, "Invalid architecture \"%s\"\nOptions: ", arch); 00199 llvm::TargetRegistry::iterator iter; 00200 for (iter = llvm::TargetRegistry::begin(); 00201 iter != llvm::TargetRegistry::end(); ++iter) 00202 fprintf(stderr, "%s ", iter->getName()); 00203 fprintf(stderr, "\n"); 00204 error = true; 00205 } 00206 else { 00207 t->arch = arch; 00208 } 00209 00210 // This is the case for most of them 00211 t->hasHalf = t->hasRand = t->hasTranscendentals = false; 00212 00213 if (!strcasecmp(isa, "sse2")) { 00214 t->isa = Target::SSE2; 00215 t->nativeVectorWidth = 4; 00216 t->vectorWidth = 4; 00217 t->attributes = "+sse,+sse2,-sse3,-sse41,-sse42,-sse4a,-ssse3,-popcnt"; 00218 t->maskingIsFree = false; 00219 t->maskBitCount = 32; 00220 } 00221 else if (!strcasecmp(isa, "sse2-x2")) { 00222 t->isa = Target::SSE2; 00223 t->nativeVectorWidth = 4; 00224 t->vectorWidth = 8; 00225 t->attributes = "+sse,+sse2,-sse3,-sse41,-sse42,-sse4a,-ssse3,-popcnt"; 00226 t->maskingIsFree = false; 00227 t->maskBitCount = 32; 00228 } 00229 else if (!strcasecmp(isa, "sse4")) { 00230 t->isa = Target::SSE4; 00231 t->nativeVectorWidth = 4; 00232 t->vectorWidth = 4; 00233 t->attributes = "+sse,+sse2,+sse3,+sse41,-sse42,-sse4a,+ssse3,-popcnt,+cmov"; 00234 t->maskingIsFree = false; 00235 t->maskBitCount = 32; 00236 } 00237 else if (!strcasecmp(isa, "sse4x2") || !strcasecmp(isa, "sse4-x2")) { 00238 t->isa = Target::SSE4; 00239 t->nativeVectorWidth = 4; 00240 t->vectorWidth = 8; 00241 t->attributes = "+sse,+sse2,+sse3,+sse41,-sse42,-sse4a,+ssse3,-popcnt,+cmov"; 00242 t->maskingIsFree = false; 00243 t->maskBitCount = 32; 00244 } 00245 else if (!strcasecmp(isa, "generic-4")) { 00246 t->isa = Target::GENERIC; 00247 t->nativeVectorWidth = 4; 00248 t->vectorWidth = 4; 00249 t->maskingIsFree = true; 00250 t->maskBitCount = 1; 00251 t->hasHalf = true; 00252 t->hasTranscendentals = true; 00253 } 00254 else if (!strcasecmp(isa, "generic-8")) { 00255 t->isa = Target::GENERIC; 00256 t->nativeVectorWidth = 8; 00257 t->vectorWidth = 8; 00258 t->maskingIsFree = true; 00259 t->maskBitCount = 1; 00260 t->hasHalf = true; 00261 t->hasTranscendentals = true; 00262 } 00263 else if (!strcasecmp(isa, "generic-16")) { 00264 t->isa = Target::GENERIC; 00265 t->nativeVectorWidth = 16; 00266 t->vectorWidth = 16; 00267 t->maskingIsFree = true; 00268 t->maskBitCount = 1; 00269 t->hasHalf = true; 00270 t->hasTranscendentals = true; 00271 } 00272 else if (!strcasecmp(isa, "generic-32")) { 00273 t->isa = Target::GENERIC; 00274 t->nativeVectorWidth = 32; 00275 t->vectorWidth = 32; 00276 t->maskingIsFree = true; 00277 t->maskBitCount = 1; 00278 t->hasHalf = true; 00279 t->hasTranscendentals = true; 00280 } 00281 else if (!strcasecmp(isa, "generic-64")) { 00282 t->isa = Target::GENERIC; 00283 t->nativeVectorWidth = 64; 00284 t->vectorWidth = 64; 00285 t->maskingIsFree = true; 00286 t->maskBitCount = 1; 00287 t->hasHalf = true; 00288 t->hasTranscendentals = true; 00289 } 00290 else if (!strcasecmp(isa, "generic-1")) { 00291 t->isa = Target::GENERIC; 00292 t->nativeVectorWidth = 1; 00293 t->vectorWidth = 1; 00294 t->maskingIsFree = false; 00295 t->maskBitCount = 32; 00296 } 00297 else if (!strcasecmp(isa, "avx") || !strcasecmp(isa, "avx1")) { 00298 t->isa = Target::AVX; 00299 t->nativeVectorWidth = 8; 00300 t->vectorWidth = 8; 00301 t->attributes = "+avx,+popcnt,+cmov"; 00302 t->maskingIsFree = false; 00303 t->maskBitCount = 32; 00304 } 00305 else if (!strcasecmp(isa, "avx-x2") || !strcasecmp(isa, "avx1-x2")) { 00306 t->isa = Target::AVX; 00307 t->nativeVectorWidth = 8; 00308 t->vectorWidth = 16; 00309 t->attributes = "+avx,+popcnt,+cmov"; 00310 t->maskingIsFree = false; 00311 t->maskBitCount = 32; 00312 } 00313 else if (!strcasecmp(isa, "avx1.1")) { 00314 t->isa = Target::AVX11; 00315 t->nativeVectorWidth = 8; 00316 t->vectorWidth = 8; 00317 t->attributes = "+avx,+popcnt,+cmov,+f16c,+rdrand"; 00318 t->maskingIsFree = false; 00319 t->maskBitCount = 32; 00320 t->hasHalf = true; 00321 t->hasRand = true; 00322 } 00323 else if (!strcasecmp(isa, "avx1.1-x2")) { 00324 t->isa = Target::AVX11; 00325 t->nativeVectorWidth = 8; 00326 t->vectorWidth = 16; 00327 t->attributes = "+avx,+popcnt,+cmov,+f16c,+rdrand"; 00328 t->maskingIsFree = false; 00329 t->maskBitCount = 32; 00330 t->hasHalf = true; 00331 t->hasRand = true; 00332 } 00333 #ifndef LLVM_3_0 00334 else if (!strcasecmp(isa, "avx2")) { 00335 t->isa = Target::AVX2; 00336 t->nativeVectorWidth = 8; 00337 t->vectorWidth = 8; 00338 t->attributes = "+avx2,+popcnt,+cmov,+f16c,+rdrand"; 00339 t->maskingIsFree = false; 00340 t->maskBitCount = 32; 00341 t->hasHalf = true; 00342 t->hasRand = true; 00343 } 00344 else if (!strcasecmp(isa, "avx2-x2")) { 00345 t->isa = Target::AVX2; 00346 t->nativeVectorWidth = 16; 00347 t->vectorWidth = 16; 00348 t->attributes = "+avx2,+popcnt,+cmov,+f16c,+rdrand"; 00349 t->maskingIsFree = false; 00350 t->maskBitCount = 32; 00351 t->hasHalf = true; 00352 t->hasRand = true; 00353 } 00354 #endif // !LLVM_3_0 00355 else { 00356 fprintf(stderr, "Target ISA \"%s\" is unknown. Choices are: %s\n", 00357 isa, SupportedTargetISAs()); 00358 error = true; 00359 } 00360 00361 if (!error) { 00362 llvm::TargetMachine *targetMachine = t->GetTargetMachine(); 00363 const llvm::TargetData *targetData = targetMachine->getTargetData(); 00364 t->is32Bit = (targetData->getPointerSize() == 4); 00365 Assert(t->vectorWidth <= ISPC_MAX_NVEC); 00366 } 00367 00368 return !error; 00369 } 00370 00371 00372 std::string 00373 Target::SupportedTargetCPUs() { 00374 std::string ret; 00375 int count = sizeof(supportedCPUs) / sizeof(supportedCPUs[0]); 00376 for (int i = 0; i < count; ++i) { 00377 ret += supportedCPUs[i]; 00378 if (i != count - 1) 00379 ret += ", "; 00380 } 00381 return ret; 00382 } 00383 00384 00385 const char * 00386 Target::SupportedTargetArchs() { 00387 return "x86, x86-64"; 00388 } 00389 00390 00391 const char * 00392 Target::SupportedTargetISAs() { 00393 return "sse2, sse2-x2, sse4, sse4-x2, avx, avx-x2" 00394 #ifndef LLVM_3_0 00395 ", avx1.1, avx1.1-x2, avx2, avx2-x2" 00396 #endif // !LLVM_3_0 00397 ", generic-1, generic-4, generic-8, generic-16, generic-32"; 00398 } 00399 00400 00401 std::string 00402 Target::GetTripleString() const { 00403 llvm::Triple triple; 00404 // Start with the host triple as the default 00405 #ifdef LLVM_3_0 00406 triple.setTriple(llvm::sys::getHostTriple()); 00407 #else 00408 triple.setTriple(llvm::sys::getDefaultTargetTriple()); 00409 #endif 00410 00411 // And override the arch in the host triple based on what the user 00412 // specified. Here we need to deal with the fact that LLVM uses one 00413 // naming convention for targets TargetRegistry, but wants some 00414 // slightly different ones for the triple. TODO: is there a way to 00415 // have it do this remapping, which would presumably be a bit less 00416 // error prone? 00417 if (arch == "x86") 00418 triple.setArchName("i386"); 00419 else if (arch == "x86-64") 00420 triple.setArchName("x86_64"); 00421 else 00422 triple.setArchName(arch); 00423 00424 return triple.str(); 00425 } 00426 00427 00428 llvm::TargetMachine * 00429 Target::GetTargetMachine() const { 00430 std::string triple = GetTripleString(); 00431 00432 llvm::Reloc::Model relocModel = generatePIC ? llvm::Reloc::PIC_ : 00433 llvm::Reloc::Default; 00434 #ifdef LLVM_3_0 00435 std::string featuresString = attributes; 00436 llvm::TargetMachine *targetMachine = 00437 target->createTargetMachine(triple, cpu, featuresString, relocModel); 00438 #else 00439 std::string featuresString = attributes; 00440 llvm::TargetOptions options; 00441 llvm::TargetMachine *targetMachine = 00442 target->createTargetMachine(triple, cpu, featuresString, options, 00443 relocModel); 00444 #endif // !LLVM_3_0 00445 Assert(targetMachine != NULL); 00446 00447 targetMachine->setAsmVerbosityDefault(true); 00448 return targetMachine; 00449 } 00450 00451 00452 const char * 00453 Target::GetISAString() const { 00454 switch (isa) { 00455 case Target::SSE2: 00456 return "sse2"; 00457 case Target::SSE4: 00458 return "sse4"; 00459 case Target::AVX: 00460 return "avx"; 00461 case Target::AVX11: 00462 return "avx11"; 00463 case Target::AVX2: 00464 return "avx2"; 00465 case Target::GENERIC: 00466 return "generic"; 00467 default: 00468 FATAL("Unhandled target in GetISAString()"); 00469 } 00470 return ""; 00471 } 00472 00473 00474 static bool 00475 lGenericTypeLayoutIndeterminate(llvm::Type *type) { 00476 if (type->isPrimitiveType() || type->isIntegerTy()) 00477 return false; 00478 00479 if (type == LLVMTypes::BoolVectorType || 00480 type == LLVMTypes::MaskType || 00481 type == LLVMTypes::Int1VectorType) 00482 return true; 00483 00484 llvm::ArrayType *at = 00485 llvm::dyn_cast<llvm::ArrayType>(type); 00486 if (at != NULL) 00487 return lGenericTypeLayoutIndeterminate(at->getElementType()); 00488 00489 llvm::PointerType *pt = 00490 llvm::dyn_cast<llvm::PointerType>(type); 00491 if (pt != NULL) 00492 return false; 00493 00494 llvm::StructType *st = 00495 llvm::dyn_cast<llvm::StructType>(type); 00496 if (st != NULL) { 00497 for (int i = 0; i < (int)st->getNumElements(); ++i) 00498 if (lGenericTypeLayoutIndeterminate(st->getElementType(i))) 00499 return true; 00500 return false; 00501 } 00502 00503 Assert(llvm::isa<llvm::VectorType>(type)); 00504 return true; 00505 } 00506 00507 00508 llvm::Value * 00509 Target::SizeOf(llvm::Type *type, 00510 llvm::BasicBlock *insertAtEnd) { 00511 if (isa == Target::GENERIC && 00512 lGenericTypeLayoutIndeterminate(type)) { 00513 llvm::Value *index[1] = { LLVMInt32(1) }; 00514 llvm::PointerType *ptrType = llvm::PointerType::get(type, 0); 00515 llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType); 00516 llvm::ArrayRef<llvm::Value *> arrayRef(&index[0], &index[1]); 00517 llvm::Instruction *gep = 00518 llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "sizeof_gep", 00519 insertAtEnd); 00520 00521 if (is32Bit || g->opt.force32BitAddressing) 00522 return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type, 00523 "sizeof_int", insertAtEnd); 00524 else 00525 return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type, 00526 "sizeof_int", insertAtEnd); 00527 } 00528 00529 const llvm::TargetData *td = GetTargetMachine()->getTargetData(); 00530 Assert(td != NULL); 00531 uint64_t bitSize = td->getTypeSizeInBits(type); 00532 Assert((bitSize % 8) == 0); 00533 uint64_t byteSize = bitSize / 8; 00534 if (is32Bit || g->opt.force32BitAddressing) 00535 return LLVMInt32((int32_t)byteSize); 00536 else 00537 return LLVMInt64(byteSize); 00538 } 00539 00540 00541 llvm::Value * 00542 Target::StructOffset(llvm::Type *type, int element, 00543 llvm::BasicBlock *insertAtEnd) { 00544 if (isa == Target::GENERIC && 00545 lGenericTypeLayoutIndeterminate(type) == true) { 00546 llvm::Value *indices[2] = { LLVMInt32(0), LLVMInt32(element) }; 00547 llvm::PointerType *ptrType = llvm::PointerType::get(type, 0); 00548 llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType); 00549 llvm::ArrayRef<llvm::Value *> arrayRef(&indices[0], &indices[2]); 00550 llvm::Instruction *gep = 00551 llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "offset_gep", 00552 insertAtEnd); 00553 00554 if (is32Bit || g->opt.force32BitAddressing) 00555 return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type, 00556 "offset_int", insertAtEnd); 00557 else 00558 return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type, 00559 "offset_int", insertAtEnd); 00560 } 00561 00562 const llvm::TargetData *td = GetTargetMachine()->getTargetData(); 00563 Assert(td != NULL); 00564 llvm::StructType *structType = 00565 llvm::dyn_cast<llvm::StructType>(type); 00566 if (structType == NULL || structType->isSized() == false) { 00567 Assert(m->errorCount > 0); 00568 return NULL; 00569 } 00570 const llvm::StructLayout *sl = td->getStructLayout(structType); 00571 Assert(sl != NULL); 00572 00573 uint64_t offset = sl->getElementOffset(element); 00574 if (is32Bit || g->opt.force32BitAddressing) 00575 return LLVMInt32((int32_t)offset); 00576 else 00577 return LLVMInt64(offset); 00578 } 00579 00580 00581 /////////////////////////////////////////////////////////////////////////// 00582 // Opt 00583 00584 Opt::Opt() { 00585 level = 1; 00586 fastMath = false; 00587 fastMaskedVload = false; 00588 force32BitAddressing = true; 00589 unrollLoops = true; 00590 disableAsserts = false; 00591 disableMaskAllOnOptimizations = false; 00592 disableHandlePseudoMemoryOps = false; 00593 disableBlendedMaskedStores = false; 00594 disableCoherentControlFlow = false; 00595 disableUniformControlFlow = false; 00596 disableGatherScatterOptimizations = false; 00597 disableMaskedStoreToStore = false; 00598 disableGatherScatterFlattening = false; 00599 disableUniformMemoryOptimizations = false; 00600 disableCoalescing = false; 00601 } 00602 00603 /////////////////////////////////////////////////////////////////////////// 00604 // Globals 00605 00606 Globals::Globals() { 00607 mathLib = Globals::Math_ISPC; 00608 00609 includeStdlib = true; 00610 runCPP = true; 00611 debugPrint = false; 00612 disableWarnings = false; 00613 warningsAsErrors = false; 00614 quiet = false; 00615 forceColoredOutput = false; 00616 disableLineWrap = false; 00617 emitPerfWarnings = true; 00618 emitInstrumentation = false; 00619 generateDebuggingSymbols = false; 00620 enableFuzzTest = false; 00621 fuzzTestSeed = -1; 00622 mangleFunctionsWithTarget = false; 00623 00624 ctx = new llvm::LLVMContext; 00625 00626 #ifdef ISPC_IS_WINDOWS 00627 _getcwd(currentDirectory, sizeof(currentDirectory)); 00628 #else 00629 if (getcwd(currentDirectory, sizeof(currentDirectory)) == NULL) 00630 FATAL("Current directory path too long!"); 00631 #endif 00632 } 00633 00634 /////////////////////////////////////////////////////////////////////////// 00635 // SourcePos 00636 00637 SourcePos::SourcePos(const char *n, int fl, int fc, int ll, int lc) { 00638 name = n; 00639 if (name == NULL) { 00640 if (m != NULL) 00641 name = m->module->getModuleIdentifier().c_str(); 00642 else 00643 name = "(unknown)"; 00644 } 00645 first_line = fl; 00646 first_column = fc; 00647 last_line = ll != 0 ? ll : fl; 00648 last_column = lc != 0 ? lc : fc; 00649 } 00650 00651 00652 llvm::DIFile 00653 SourcePos::GetDIFile() const { 00654 std::string directory, filename; 00655 GetDirectoryAndFileName(g->currentDirectory, name, &directory, &filename); 00656 llvm::DIFile ret = m->diBuilder->createFile(filename, directory); 00657 Assert(ret.Verify()); 00658 return ret; 00659 } 00660 00661 00662 void 00663 SourcePos::Print() const { 00664 printf(" @ [%s:%d.%d - %d.%d] ", name, first_line, first_column, 00665 last_line, last_column); 00666 } 00667 00668 00669 bool 00670 SourcePos::operator==(const SourcePos &p2) const { 00671 return (!strcmp(name, p2.name) && 00672 first_line == p2.first_line && 00673 first_column == p2.first_column && 00674 last_line == p2.last_line && 00675 last_column == p2.last_column); 00676 } 00677 00678 00679 SourcePos 00680 Union(const SourcePos &p1, const SourcePos &p2) { 00681 if (strcmp(p1.name, p2.name) != 0) 00682 return p1; 00683 00684 SourcePos ret; 00685 ret.name = p1.name; 00686 ret.first_line = std::min(p1.first_line, p2.first_line); 00687 ret.first_column = std::min(p1.first_column, p2.first_column); 00688 ret.last_line = std::max(p1.last_line, p2.last_line); 00689 ret.last_column = std::max(p1.last_column, p2.last_column); 00690 return ret; 00691 }
1.7.5.1