void bcc::init::Initialize() { static bool is_initialized = false; if (is_initialized) { return; } // Setup error handler for LLVM. llvm::remove_fatal_error_handler(); llvm::install_fatal_error_handler(llvm_error_handler, NULL); #if defined(PROVIDE_ARM_CODEGEN) LLVMInitializeARMAsmPrinter(); # if USE_DISASSEMBLER LLVMInitializeARMDisassembler(); # endif LLVMInitializeARMTargetMC(); LLVMInitializeARMTargetInfo(); LLVMInitializeARMTarget(); MCLDInitializeARMLDTargetInfo(); MCLDInitializeARMLDTarget(); MCLDInitializeARMLDBackend(); MCLDInitializeARMDiagnosticLineInfo(); #endif #if defined(PROVIDE_MIPS_CODEGEN) LLVMInitializeMipsAsmPrinter(); # if USE_DISASSEMBLER LLVMInitializeMipsDisassembler(); # endif LLVMInitializeMipsTargetMC(); LLVMInitializeMipsTargetInfo(); LLVMInitializeMipsTarget(); MCLDInitializeMipsLDTargetInfo(); MCLDInitializeMipsLDTarget(); MCLDInitializeMipsLDBackend(); MCLDInitializeMipsDiagnosticLineInfo(); #endif #if defined(PROVIDE_X86_CODEGEN) LLVMInitializeX86AsmPrinter(); # if USE_DISASSEMBLER LLVMInitializeX86Disassembler(); # endif LLVMInitializeX86TargetMC(); LLVMInitializeX86TargetInfo(); LLVMInitializeX86Target(); MCLDInitializeX86LDTargetInfo(); MCLDInitializeX86LDTarget(); MCLDInitializeX86LDBackend(); MCLDInitializeX86DiagnosticLineInfo(); #endif is_initialized = true; return; }
int main() { int tmp; LLVMInitializeX86TargetInfo(); LLVMInitializeX86TargetMC(); LLVMInitializeX86AsmParser(); LLVMInitializeX86Disassembler(); tmp = llvm::build_reg_table(); if (tmp) { llvm::outs() << llvm::format("tmp = 0x%x\n", tmp); } return 0; }
extern "C" JSC::LLVMAPI* initializeAndGetJSCLLVMAPI(void (*callback)(const char*, ...)) { g_llvmTrapCallback = callback; LLVMInstallFatalErrorHandler(llvmCrash); if (!LLVMStartMultithreaded()) callback("Could not start LLVM multithreading"); LLVMLinkInMCJIT(); // You think you want to call LLVMInitializeNativeTarget()? Think again. This presumes that // LLVM was ./configured correctly, which won't be the case in cross-compilation situations. #if CPU(X86_64) LLVMInitializeX86TargetInfo(); LLVMInitializeX86Target(); LLVMInitializeX86TargetMC(); LLVMInitializeX86AsmPrinter(); LLVMInitializeX86Disassembler(); #elif CPU(ARM64) LLVMInitializeARM64TargetInfo(); LLVMInitializeARM64Target(); LLVMInitializeARM64TargetMC(); LLVMInitializeARM64AsmPrinter(); LLVMInitializeARM64Disassembler(); #else UNREACHABLE_FOR_PLATFORM(); #endif const char* args[] = { "llvmForJSC.dylib", "-enable-stackmap-liveness=true", "-enable-patchpoint-liveness=true" }; llvm::cl::ParseCommandLineOptions(sizeof(args) / sizeof(const char*), args); JSC::LLVMAPI* result = new JSC::LLVMAPI; #define LLVM_API_FUNCTION_ASSIGNMENT(returnType, name, signature) \ result->name = LLVM##name; FOR_EACH_LLVM_API_FUNCTION(LLVM_API_FUNCTION_ASSIGNMENT); #undef LLVM_API_FUNCTION_ASSIGNMENT return result; }
extern "C" JSC::LLVMAPI* initializeAndGetJSCLLVMAPI(void (*callback)(const char*, ...)) { g_llvmTrapCallback = callback; LLVMInstallFatalErrorHandler(llvmCrash); if (!LLVMStartMultithreaded()) callback("Could not start LLVM multithreading"); LLVMLinkInMCJIT(); LLVMInitializeNativeTarget(); LLVMInitializeX86AsmPrinter(); LLVMInitializeX86Disassembler(); JSC::LLVMAPI* result = new JSC::LLVMAPI; #define LLVM_API_FUNCTION_ASSIGNMENT(returnType, name, signature) \ result->name = LLVM##name; FOR_EACH_LLVM_API_FUNCTION(LLVM_API_FUNCTION_ASSIGNMENT); #undef LLVM_API_FUNCTION_ASSIGNMENT return result; }
int main(int Argc, char *Argv[]) { int argc; char *argv[128]; lGetAllArgs(Argc, Argv, argc, argv); llvm::sys::AddSignalHandler(lSignal, NULL); // initialize available LLVM targets #ifndef __arm__ // FIXME: LLVM build on ARM doesn't build the x86 targets by default. // It's not clear that anyone's going to want to generate x86 from an // ARM host, though... LLVMInitializeX86TargetInfo(); LLVMInitializeX86Target(); LLVMInitializeX86AsmPrinter(); LLVMInitializeX86AsmParser(); LLVMInitializeX86Disassembler(); LLVMInitializeX86TargetMC(); #endif // !__ARM__ #ifdef ISPC_ARM_ENABLED // Generating ARM from x86 is more likely to be useful, though. LLVMInitializeARMTargetInfo(); LLVMInitializeARMTarget(); LLVMInitializeARMAsmPrinter(); LLVMInitializeARMAsmParser(); LLVMInitializeARMDisassembler(); LLVMInitializeARMTargetMC(); #endif #ifdef ISPC_NVPTX_ENABLED LLVMInitializeNVPTXTargetInfo(); LLVMInitializeNVPTXTarget(); LLVMInitializeNVPTXAsmPrinter(); LLVMInitializeNVPTXTargetMC(); #endif /* ISPC_NVPTX_ENABLED */ char *file = NULL; const char *headerFileName = NULL; const char *outFileName = NULL; const char *includeFileName = NULL; const char *depsFileName = NULL; const char *hostStubFileName = NULL; const char *devStubFileName = NULL; // Initiailize globals early so that we can set various option values // as we're parsing below g = new Globals; Module::OutputType ot = Module::Object; bool generatePIC = false; const char *arch = NULL, *cpu = NULL, *target = NULL; for (int i = 1; i < argc; ++i) { if (!strcmp(argv[i], "--help")) usage(0); if (!strcmp(argv[i], "--help-dev")) devUsage(0); else if (!strncmp(argv[i], "-D", 2)) g->cppArgs.push_back(argv[i]); else if (!strncmp(argv[i], "--addressing=", 13)) { if (atoi(argv[i] + 13) == 64) // FIXME: this doesn't make sense on 32 bit platform. g->opt.force32BitAddressing = false; else if (atoi(argv[i] + 13) == 32) g->opt.force32BitAddressing = true; else { fprintf(stderr, "Addressing width \"%s\" invalid--only 32 and " "64 are allowed.\n", argv[i]+13); usage(1); } } else if (!strncmp(argv[i], "--arch=", 7)) arch = argv[i] + 7; else if (!strncmp(argv[i], "--cpu=", 6)) cpu = argv[i] + 6; else if (!strcmp(argv[i], "--fast-math")) { fprintf(stderr, "--fast-math option has been renamed to --opt=fast-math!\n"); usage(1); } else if (!strcmp(argv[i], "--fast-masked-vload")) { fprintf(stderr, "--fast-masked-vload option has been renamed to " "--opt=fast-masked-vload!\n"); usage(1); } else if (!strcmp(argv[i], "--debug")) g->debugPrint = true; else if (!strcmp(argv[i], "--instrument")) g->emitInstrumentation = true; else if (!strcmp(argv[i], "-g")) { g->generateDebuggingSymbols = true; } else if (!strcmp(argv[i], "--emit-asm")) ot = Module::Asm; else if (!strcmp(argv[i], "--emit-c++")) ot = Module::CXX; else if (!strcmp(argv[i], "--emit-llvm")) ot = Module::Bitcode; else if (!strcmp(argv[i], "--emit-obj")) ot = Module::Object; else if (!strcmp(argv[i], "-I")) { if (++i == argc) { fprintf(stderr, "No path specified after -I option.\n"); usage(1); } lParseInclude(argv[i]); } else if (!strncmp(argv[i], "-I", 2)) lParseInclude(argv[i]+2); else if (!strcmp(argv[i], "--fuzz-test")) g->enableFuzzTest = true; else if (!strncmp(argv[i], "--fuzz-seed=", 12)) g->fuzzTestSeed = atoi(argv[i] + 12); else if (!strcmp(argv[i], "--target")) { // FIXME: should remove this way of specifying the target... if (++i == argc) { fprintf(stderr, "No target specified after --target option.\n"); usage(1); } target = argv[i]; } else if (!strncmp(argv[i], "--target=", 9)) target = argv[i] + 9; else if (!strncmp(argv[i], "--math-lib=", 11)) { const char *lib = argv[i] + 11; if (!strcmp(lib, "default")) g->mathLib = Globals::Math_ISPC; else if (!strcmp(lib, "fast")) g->mathLib = Globals::Math_ISPCFast; else if (!strcmp(lib, "svml")) g->mathLib = Globals::Math_SVML; else if (!strcmp(lib, "system")) g->mathLib = Globals::Math_System; else { fprintf(stderr, "Unknown --math-lib= option \"%s\".\n", lib); usage(1); } } else if (!strncmp(argv[i], "--opt=", 6)) { const char *opt = argv[i] + 6; if (!strcmp(opt, "fast-math")) g->opt.fastMath = true; else if (!strcmp(opt, "fast-masked-vload")) g->opt.fastMaskedVload = true; else if (!strcmp(opt, "disable-assertions")) g->opt.disableAsserts = true; else if (!strcmp(opt, "disable-loop-unroll")) g->opt.unrollLoops = false; else if (!strcmp(opt, "disable-fma")) g->opt.disableFMA = true; else if (!strcmp(opt, "force-aligned-memory")) g->opt.forceAlignedMemory = true; // These are only used for performance tests of specific // optimizations else if (!strcmp(opt, "disable-all-on-optimizations")) g->opt.disableMaskAllOnOptimizations = true; else if (!strcmp(opt, "disable-coalescing")) g->opt.disableCoalescing = true; else if (!strcmp(opt, "disable-handle-pseudo-memory-ops")) g->opt.disableHandlePseudoMemoryOps = true; else if (!strcmp(opt, "disable-blended-masked-stores")) g->opt.disableBlendedMaskedStores = true; else if (!strcmp(opt, "disable-coherent-control-flow")) g->opt.disableCoherentControlFlow = true; else if (!strcmp(opt, "disable-uniform-control-flow")) g->opt.disableUniformControlFlow = true; else if (!strcmp(opt, "disable-gather-scatter-optimizations")) g->opt.disableGatherScatterOptimizations = true; else if (!strcmp(opt, "disable-blending-removal")) g->opt.disableMaskedStoreToStore = true; else if (!strcmp(opt, "disable-gather-scatter-flattening")) g->opt.disableGatherScatterFlattening = true; else if (!strcmp(opt, "disable-uniform-memory-optimizations")) g->opt.disableUniformMemoryOptimizations = true; else { fprintf(stderr, "Unknown --opt= option \"%s\".\n", opt); usage(1); } } else if (!strncmp(argv[i], "--force-alignment=", 18)) { g->forceAlignment = atoi(argv[i] + 18); } else if (!strcmp(argv[i], "--woff") || !strcmp(argv[i], "-woff")) { g->disableWarnings = true; g->emitPerfWarnings = false; } else if (!strcmp(argv[i], "--werror")) g->warningsAsErrors = true; else if (!strcmp(argv[i], "--nowrap")) g->disableLineWrap = true; else if (!strcmp(argv[i], "--wno-perf") || !strcmp(argv[i], "-wno-perf")) g->emitPerfWarnings = false; else if (!strcmp(argv[i], "-o")) { if (++i == argc) { fprintf(stderr, "No output file specified after -o option.\n"); usage(1); } outFileName = argv[i]; } else if (!strncmp(argv[i], "--outfile=", 10)) outFileName = argv[i] + strlen("--outfile="); else if (!strcmp(argv[i], "-h")) { if (++i == argc) { fprintf(stderr, "No header file name specified after -h option.\n"); usage(1); } headerFileName = argv[i]; } else if (!strncmp(argv[i], "--header-outfile=", 17)) { headerFileName = argv[i] + strlen("--header-outfile="); } else if (!strncmp(argv[i], "--c++-include-file=", 19)) { includeFileName = argv[i] + strlen("--c++-include-file="); } else if (!strcmp(argv[i], "-O0")) { g->opt.level = 0; } else if (!strcmp(argv[i], "-O") || !strcmp(argv[i], "-O1") || !strcmp(argv[i], "-O2") || !strcmp(argv[i], "-O3")) { g->opt.level = 1; } else if (!strcmp(argv[i], "-")) ; else if (!strcmp(argv[i], "--nostdlib")) g->includeStdlib = false; else if (!strcmp(argv[i], "--nocpp")) g->runCPP = false; #ifndef ISPC_IS_WINDOWS else if (!strcmp(argv[i], "--pic")) generatePIC = true; else if (!strcmp(argv[i], "--colored-output")) g->forceColoredOutput = true; #endif // !ISPC_IS_WINDOWS else if (!strcmp(argv[i], "--quiet")) g->quiet = true; else if (!strcmp(argv[i], "--yydebug")) { extern int yydebug; yydebug = 1; } else if (!strcmp(argv[i], "-MMM")) { if (++i == argc) { fprintf(stderr, "No output file name specified after -MMM option.\n"); usage(1); } depsFileName = argv[i]; } else if (!strcmp(argv[i], "--dev-stub")) { if (++i == argc) { fprintf(stderr, "No output file name specified after --dev-stub option.\n"); usage(1); } devStubFileName = argv[i]; } else if (!strcmp(argv[i], "--host-stub")) { if (++i == argc) { fprintf(stderr, "No output file name specified after --host-stub option.\n"); usage(1); } hostStubFileName = argv[i]; } else if (strncmp(argv[i], "--debug-phase=", 14) == 0) { fprintf(stderr, "WARNING: Adding debug phases may change the way PassManager" "handles the phases and it may possibly make some bugs go" "away or introduce the new ones.\n"); g->debug_stages = ParsingPhases(argv[i] + strlen("--debug-phase=")); } #if !defined(LLVM_3_2) && !defined(LLVM_3_3) // LLVM 3.4+ else if (strncmp(argv[i], "--debug-ir=", 11) == 0) { g->debugIR = ParsingPhaseName(argv[i] + strlen("--debug-ir=")); } #endif else if (strncmp(argv[i], "--off-phase=", 12) == 0) { g->off_stages = ParsingPhases(argv[i] + strlen("--off-phase=")); } else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { lPrintVersion(); return 0; } else if (argv[i][0] == '-') { fprintf(stderr, "Unknown option \"%s\".\n", argv[i]); usage(1); } else { if (file != NULL) { fprintf(stderr, "Multiple input files specified on command " "line: \"%s\" and \"%s\".\n", file, argv[i]); usage(1); } else file = argv[i]; } } if (g->enableFuzzTest) { if (g->fuzzTestSeed == -1) { #ifdef ISPC_IS_WINDOWS int seed = (unsigned)time(NULL); #else int seed = getpid(); #endif g->fuzzTestSeed = seed; Warning(SourcePos(), "Using seed %d for fuzz testing", g->fuzzTestSeed); } #ifdef ISPC_IS_WINDOWS srand(g->fuzzTestSeed); #else srand48(g->fuzzTestSeed); #endif } if (outFileName == NULL && headerFileName == NULL && depsFileName == NULL && hostStubFileName == NULL && devStubFileName == NULL) Warning(SourcePos(), "No output file or header file name specified. " "Program will be compiled and warnings/errors will " "be issued, but no output will be generated."); return Module::CompileAndOutput(file, arch, cpu, target, generatePIC, ot, outFileName, headerFileName, includeFileName, depsFileName, hostStubFileName, devStubFileName); }
int main(int Argc, char *Argv[]) { int argc; char *argv[128]; lGetAllArgs(Argc, Argv, argc, argv); llvm::sys::AddSignalHandler(lSignal, NULL); // initialize available LLVM targets LLVMInitializeX86TargetInfo(); LLVMInitializeX86Target(); LLVMInitializeX86AsmPrinter(); LLVMInitializeX86AsmParser(); LLVMInitializeX86Disassembler(); LLVMInitializeX86TargetMC(); char *file = NULL; const char *headerFileName = NULL; const char *outFileName = NULL; const char *includeFileName = NULL; // Initiailize globals early so that we can set various option values // as we're parsing below g = new Globals; bool debugSet = false, optSet = false; Module::OutputType ot = Module::Object; bool generatePIC = false; const char *arch = NULL, *cpu = NULL, *target = NULL; for (int i = 1; i < argc; ++i) { if (!strcmp(argv[i], "--help")) usage(0); if (!strcmp(argv[i], "--help-dev")) devUsage(0); else if (!strncmp(argv[i], "-D", 2)) g->cppArgs.push_back(argv[i]); else if (!strncmp(argv[i], "--addressing=", 13)) { if (atoi(argv[i] + 13) == 64) g->opt.force32BitAddressing = false; else if (atoi(argv[i] + 13) == 32) g->opt.force32BitAddressing = true; else { fprintf(stderr, "Addressing width \"%s\" invalid--only 32 and " "64 are allowed.\n", argv[i]+13); usage(1); } } else if (!strncmp(argv[i], "--arch=", 7)) arch = argv[i] + 7; else if (!strncmp(argv[i], "--cpu=", 6)) cpu = argv[i] + 6; else if (!strcmp(argv[i], "--fast-math")) { fprintf(stderr, "--fast-math option has been renamed to --opt=fast-math!\n"); usage(1); } else if (!strcmp(argv[i], "--fast-masked-vload")) { fprintf(stderr, "--fast-masked-vload option has been renamed to " "--opt=fast-masked-vload!\n"); usage(1); } else if (!strcmp(argv[i], "--debug")) g->debugPrint = true; else if (!strcmp(argv[i], "--instrument")) g->emitInstrumentation = true; else if (!strcmp(argv[i], "-g")) { g->generateDebuggingSymbols = true; debugSet = true; } else if (!strcmp(argv[i], "--emit-asm")) ot = Module::Asm; else if (!strcmp(argv[i], "--emit-c++")) ot = Module::CXX; else if (!strcmp(argv[i], "--emit-llvm")) ot = Module::Bitcode; else if (!strcmp(argv[i], "--emit-obj")) ot = Module::Object; else if (!strcmp(argv[i], "-I")) { if (++i == argc) { fprintf(stderr, "No path specified after -I option.\n"); usage(1); } g->includePath.push_back(argv[i]); } else if (!strncmp(argv[i], "-I", 2)) g->includePath.push_back(argv[i]+2); else if (!strcmp(argv[i], "--fuzz-test")) g->enableFuzzTest = true; else if (!strncmp(argv[i], "--fuzz-seed=", 12)) g->fuzzTestSeed = atoi(argv[i] + 12); else if (!strcmp(argv[i], "--target")) { // FIXME: should remove this way of specifying the target... if (++i == argc) { fprintf(stderr, "No target specified after --target option.\n"); usage(1); } target = argv[i]; } else if (!strncmp(argv[i], "--target=", 9)) target = argv[i] + 9; else if (!strncmp(argv[i], "--math-lib=", 11)) { const char *lib = argv[i] + 11; if (!strcmp(lib, "default")) g->mathLib = Globals::Math_ISPC; else if (!strcmp(lib, "fast")) g->mathLib = Globals::Math_ISPCFast; else if (!strcmp(lib, "svml")) g->mathLib = Globals::Math_SVML; else if (!strcmp(lib, "system")) g->mathLib = Globals::Math_System; else { fprintf(stderr, "Unknown --math-lib= option \"%s\".\n", lib); usage(1); } } else if (!strncmp(argv[i], "--opt=", 6)) { const char *opt = argv[i] + 6; if (!strcmp(opt, "fast-math")) g->opt.fastMath = true; else if (!strcmp(opt, "fast-masked-vload")) g->opt.fastMaskedVload = true; else if (!strcmp(opt, "disable-assertions")) g->opt.disableAsserts = true; else if (!strcmp(opt, "disable-loop-unroll")) g->opt.unrollLoops = false; // These are only used for performance tests of specific // optimizations else if (!strcmp(opt, "disable-all-on-optimizations")) g->opt.disableMaskAllOnOptimizations = true; else if (!strcmp(opt, "disable-coalescing")) g->opt.disableCoalescing = true; else if (!strcmp(opt, "disable-handle-pseudo-memory-ops")) g->opt.disableHandlePseudoMemoryOps = true; else if (!strcmp(opt, "disable-blended-masked-stores")) g->opt.disableBlendedMaskedStores = true; else if (!strcmp(opt, "disable-coherent-control-flow")) g->opt.disableCoherentControlFlow = true; else if (!strcmp(opt, "disable-uniform-control-flow")) g->opt.disableUniformControlFlow = true; else if (!strcmp(opt, "disable-gather-scatter-optimizations")) g->opt.disableGatherScatterOptimizations = true; else if (!strcmp(opt, "disable-blending-removal")) g->opt.disableMaskedStoreToStore = true; else if (!strcmp(opt, "disable-gather-scatter-flattening")) g->opt.disableGatherScatterFlattening = true; else if (!strcmp(opt, "disable-uniform-memory-optimizations")) g->opt.disableUniformMemoryOptimizations = true; else { fprintf(stderr, "Unknown --opt= option \"%s\".\n", opt); usage(1); } } else if (!strcmp(argv[i], "--woff") || !strcmp(argv[i], "-woff")) { g->disableWarnings = true; g->emitPerfWarnings = false; } else if (!strcmp(argv[i], "--werror")) g->warningsAsErrors = true; else if (!strcmp(argv[i], "--nowrap")) g->disableLineWrap = true; else if (!strcmp(argv[i], "--wno-perf") || !strcmp(argv[i], "-wno-perf")) g->emitPerfWarnings = false; else if (!strcmp(argv[i], "-o")) { if (++i == argc) { fprintf(stderr, "No output file specified after -o option.\n"); usage(1); } outFileName = argv[i]; } else if (!strncmp(argv[i], "--outfile=", 10)) outFileName = argv[i] + strlen("--outfile="); else if (!strcmp(argv[i], "-h")) { if (++i == argc) { fprintf(stderr, "No header file name specified after -h option.\n"); usage(1); } headerFileName = argv[i]; } else if (!strncmp(argv[i], "--header-outfile=", 17)) { headerFileName = argv[i] + strlen("--header-outfile="); } else if (!strncmp(argv[i], "--c++-include-file=", 19)) { includeFileName = argv[i] + strlen("--c++-include-file="); } else if (!strcmp(argv[i], "-O0")) { g->opt.level = 0; optSet = true; } else if (!strcmp(argv[i], "-O") || !strcmp(argv[i], "-O1") || !strcmp(argv[i], "-O2") || !strcmp(argv[i], "-O3")) { g->opt.level = 1; optSet = true; } else if (!strcmp(argv[i], "-")) ; else if (!strcmp(argv[i], "--nostdlib")) g->includeStdlib = false; else if (!strcmp(argv[i], "--nocpp")) g->runCPP = false; #ifndef ISPC_IS_WINDOWS else if (!strcmp(argv[i], "--pic")) generatePIC = true; #endif // !ISPC_IS_WINDOWS else if (!strcmp(argv[i], "--quiet")) g->quiet = true; else if (!strcmp(argv[i], "--yydebug")) { extern int yydebug; yydebug = 1; } else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { lPrintVersion(); return 0; } else if (argv[i][0] == '-') { fprintf(stderr, "Unknown option \"%s\".\n", argv[i]); usage(1); } else { if (file != NULL) { fprintf(stderr, "Multiple input files specified on command " "line: \"%s\" and \"%s\".\n", file, argv[i]); usage(1); } else file = argv[i]; } } // If the user specified -g, then the default optimization level is 0. // If -g wasn't specified, the default optimization level is 1 (full // optimization). if (debugSet && !optSet) g->opt.level = 0; if (g->enableFuzzTest) { if (g->fuzzTestSeed == -1) { #ifdef ISPC_IS_WINDOWS int seed = (unsigned)time(NULL); #else int seed = getpid(); #endif g->fuzzTestSeed = seed; Warning(SourcePos(), "Using seed %d for fuzz testing", g->fuzzTestSeed); } #ifdef ISPC_IS_WINDOWS srand(g->fuzzTestSeed); #else srand48(g->fuzzTestSeed); #endif } if (outFileName == NULL && headerFileName == NULL) Warning(SourcePos(), "No output file or header file name specified. " "Program will be compiled and warnings/errors will " "be issued, but no output will be generated."); return Module::CompileAndOutput(file, arch, cpu, target, generatePIC, ot, outFileName, headerFileName, includeFileName); }
int main(int c, char **v) { LLVMContextRef *contexts; LLVMModuleRef *modules; char *error; const char *mode = "opt"; const char **filenames; unsigned numFiles; unsigned i; bool moreOptions; static int verboseFlag = 0; static int timingFlag = 0; static int disassembleFlag = 0; bool manyContexts = true; double beforeAll; if (c == 1) usage(); moreOptions = true; while (moreOptions) { static struct option longOptions[] = { {"verbose", no_argument, &verboseFlag, 1}, {"timing", no_argument, &timingFlag, 1}, {"disassemble", no_argument, &disassembleFlag, 1}, {"mode", required_argument, 0, 0}, {"contexts", required_argument, 0, 0}, {"help", no_argument, 0, 0} }; int optionIndex; int optionValue; optionValue = getopt_long(c, v, "", longOptions, &optionIndex); switch (optionValue) { case -1: moreOptions = false; break; case 0: { const char* thisOption = longOptions[optionIndex].name; if (!strcmp(thisOption, "help")) usage(); if (!strcmp(thisOption, "contexts")) { if (!strcasecmp(optarg, "one")) manyContexts = false; else if (!strcasecmp(optarg, "many")) manyContexts = true; else { fprintf(stderr, "Invalid argument for --contexts.\n"); exit(1); } break; } if (!strcmp(thisOption, "mode")) { mode = strdup(optarg); break; } break; } case '?': exit(0); break; default: printf("optionValue = %d\n", optionValue); abort(); break; } } LLVMLinkInMCJIT(); LLVMInitializeNativeTarget(); LLVMInitializeX86AsmPrinter(); LLVMInitializeX86Disassembler(); filenames = (const char **)(v + optind); numFiles = c - optind; contexts = malloc(sizeof(LLVMContextRef) * numFiles); modules = malloc(sizeof(LLVMModuleRef) * numFiles); if (manyContexts) { for (i = 0; i < numFiles; ++i) contexts[i] = LLVMContextCreate(); } else { LLVMContextRef context = LLVMContextCreate(); for (i = 0; i < numFiles; ++i) contexts[i] = context; } for (i = 0; i < numFiles; ++i) { LLVMMemoryBufferRef buffer; const char* filename = filenames[i]; if (LLVMCreateMemoryBufferWithContentsOfFile(filename, &buffer, &error)) { fprintf(stderr, "Error reading file %s: %s\n", filename, error); exit(1); } if (LLVMParseBitcodeInContext(contexts[i], buffer, modules + i, &error)) { fprintf(stderr, "Error parsing file %s: %s\n", filename, error); exit(1); } LLVMDisposeMemoryBuffer(buffer); if (verboseFlag) { printf("Module #%u (%s) after parsing:\n", i, filename); LLVMDumpModule(modules[i]); } } if (verboseFlag) printf("Generating code for modules...\n"); if (timingFlag) beforeAll = currentTime(); for (i = 0; i < numFiles; ++i) { LLVMModuleRef module; LLVMExecutionEngineRef engine; struct LLVMMCJITCompilerOptions options; LLVMValueRef value; LLVMPassManagerRef functionPasses = 0; LLVMPassManagerRef modulePasses = 0; double before; if (timingFlag) before = currentTime(); module = modules[i]; LLVMInitializeMCJITCompilerOptions(&options, sizeof(options)); options.OptLevel = 2; options.EnableFastISel = 0; options.MCJMM = LLVMCreateSimpleMCJITMemoryManager( 0, mmAllocateCodeSection, mmAllocateDataSection, mmApplyPermissions, mmDestroy); if (LLVMCreateMCJITCompilerForModule(&engine, module, &options, sizeof(options), &error)) { fprintf(stderr, "Error building MCJIT: %s\n", error); exit(1); } if (!strcasecmp(mode, "simple")) { modulePasses = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), modulePasses); LLVMAddConstantPropagationPass(modulePasses); LLVMAddInstructionCombiningPass(modulePasses); LLVMAddPromoteMemoryToRegisterPass(modulePasses); LLVMAddBasicAliasAnalysisPass(modulePasses); LLVMAddTypeBasedAliasAnalysisPass(modulePasses); LLVMAddGVNPass(modulePasses); LLVMAddCFGSimplificationPass(modulePasses); LLVMRunPassManager(modulePasses, module); } else if (!strcasecmp(mode, "opt")) { LLVMPassManagerBuilderRef passBuilder; passBuilder = LLVMPassManagerBuilderCreate(); LLVMPassManagerBuilderSetOptLevel(passBuilder, 2); LLVMPassManagerBuilderSetSizeLevel(passBuilder, 0); functionPasses = LLVMCreateFunctionPassManagerForModule(module); modulePasses = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), modulePasses); LLVMPassManagerBuilderPopulateFunctionPassManager(passBuilder, functionPasses); LLVMPassManagerBuilderPopulateModulePassManager(passBuilder, modulePasses); LLVMPassManagerBuilderDispose(passBuilder); LLVMInitializeFunctionPassManager(functionPasses); for (value = LLVMGetFirstFunction(module); value; value = LLVMGetNextFunction(value)) LLVMRunFunctionPassManager(functionPasses, value); LLVMFinalizeFunctionPassManager(functionPasses); LLVMRunPassManager(modulePasses, module); } else { fprintf(stderr, "Bad optimization mode: %s.\n", mode); fprintf(stderr, "Valid modes are: \"simple\" or \"opt\".\n"); exit(1); } if (verboseFlag) { printf("Module #%d (%s) after optimization:\n", i, filenames[i]); LLVMDumpModule(module); } for (value = LLVMGetFirstFunction(module); value; value = LLVMGetNextFunction(value)) { if (LLVMIsDeclaration(value)) continue; LLVMGetPointerToGlobal(engine, value); } if (functionPasses) LLVMDisposePassManager(functionPasses); if (modulePasses) LLVMDisposePassManager(modulePasses); LLVMDisposeExecutionEngine(engine); if (timingFlag) { double after = currentTime(); printf("Module #%d (%s) took %lf ms.\n", i, filenames[i], (after - before) * 1000); } } if (timingFlag) { double after = currentTime(); printf("Compilation took a total of %lf ms.\n", (after - beforeAll) * 1000); } if (disassembleFlag) { LLVMDisasmContextRef disassembler; struct MemorySection *section; disassembler = LLVMCreateDisasm("x86_64-apple-darwin", 0, 0, 0, symbolLookupCallback); if (!disassembler) { fprintf(stderr, "Error building disassembler.\n"); exit(1); } for (section = sectionHead; section; section = section->next) { printf("Disassembly for section %p:\n", section); char pcString[20]; char instructionString[1000]; uint8_t *pc; uint8_t *end; pc = section->start; end = pc + section->size; while (pc < end) { snprintf( pcString, sizeof(pcString), "0x%lx", (unsigned long)(uintptr_t)pc); size_t instructionSize = LLVMDisasmInstruction( disassembler, pc, end - pc, (uintptr_t)pc, instructionString, sizeof(instructionString)); if (!instructionSize) snprintf(instructionString, sizeof(instructionString), ".byte 0x%02x", *pc++); else pc += instructionSize; printf(" %16s: %s\n", pcString, instructionString); } } } return 0; }
void disassemblyInitialize() { LLVMInitializeX86Disassembler(); llvm::InitializeNativeTargetAsmPrinter(); llvm::InitializeNativeTargetAsmParser(); }