Exemplo n.º 1
0
void Codegen::createPasses() {

    llvm::TargetMachine *tm = targetMachine();
//    llvm::DataLayout *dl = new llvm::DataLayout(&llvmModule());

    modulePasses = new llvm::PassManager();
//     modulePasses->add(dl);
    functionPasses = new llvm::FunctionPassManager(&llvmModule());
//    functionPasses->add(dl);

    tm->addAnalysisPasses(*modulePasses);
    tm->addAnalysisPasses(*functionPasses);

    llvm::PassManagerBuilder pmBuilder;
    pmBuilder.OptLevel = options.optLevel;

    llvm::Triple targetTriple(llvmModule().getTargetTriple());
    pmBuilder.LibraryInfo = new llvm::TargetLibraryInfo(targetTriple);

    if (nativeEnabled()) {
        codegenPasses = new llvm::PassManager();
//        codegenPasses->add(dl);
        //codegenPasses->add(pmBuilder.LibraryInfo);
        tm->addAnalysisPasses(*codegenPasses);
    }

    unsigned inlineThreshold = 225;
    if (options.optLevel > 2) {
        inlineThreshold = 275;
        modulePasses->add(llvm::createStripSymbolsPass(true));
    }
    pmBuilder.Inliner = llvm::createFunctionInliningPass(inlineThreshold);
    pmBuilder.populateFunctionPassManager(*functionPasses);
    pmBuilder.populateModulePassManager(*modulePasses);
}
Exemplo n.º 2
0
std::string generatePtx(llvm::Module *module, int devMajor, int devMinor) {
  std::string mcpu;
  if ((devMajor == 3 && devMinor >= 5) ||
      devMajor > 3) {
    mcpu = "sm_35";
  }
  else if (devMajor >= 3 && devMinor >= 0) {
    mcpu = "sm_30";
  }
  else {
    mcpu = "sm_20";
  }

  // Select target given the module's triple
  llvm::Triple triple(module->getTargetTriple());
  std::string errStr;
  const llvm::Target* target = nullptr;
  target = llvm::TargetRegistry::lookupTarget(triple.str(), errStr);
  iassert(target) << errStr;

  llvm::TargetOptions targetOptions;

  std::string features = "+ptx40";

  std::unique_ptr<llvm::TargetMachine> targetMachine(
      target->createTargetMachine(triple.str(), mcpu, features, targetOptions,
                                  // llvm::Reloc::PIC_,
                                  llvm::Reloc::Default,
                                  llvm::CodeModel::Default,
                                  llvm::CodeGenOpt::Default));

  // Make a passmanager and add emission to string
  llvm::legacy::PassManager pm;
  pm.add(new llvm::TargetLibraryInfoWrapperPass(triple));

  // Set up constant NVVM reflect mapping
  llvm::StringMap<int> reflectMapping;
  reflectMapping["__CUDA_FTZ"] = 1; // Flush denormals to zero
  pm.add(llvm::createNVVMReflectPass(reflectMapping));
  pm.add(llvm::createAlwaysInlinerPass());
  targetMachine->Options.MCOptions.AsmVerbose = true;
  llvm::SmallString<8> ptxStr;
  llvm::raw_svector_ostream outStream(ptxStr);
  outStream.SetUnbuffered();
  bool failed = targetMachine->addPassesToEmitFile(
      pm, outStream, targetMachine->CGFT_AssemblyFile, false);
  iassert(!failed);

  pm.run(*module);
  outStream.flush();
  return ptxStr.str();
}
Exemplo n.º 3
0
void Codegen::emitCode(llvm::raw_ostream *os) {
    llvm::formatted_raw_ostream formattedOS;

    createPasses();

    llvm::TargetMachine::CodeGenFileType cgft = llvm::TargetMachine::CGFT_AssemblyFile;
    switch (options.type) {
    case codegen::LLVM:
        formattedOS.setStream(*os, llvm::formatted_raw_ostream::PRESERVE_STREAM);
        modulePasses->add(llvm::createPrintModulePass(*os));
        break;
    case codegen::BC:
        modulePasses->add(llvm::createBitcodeWriterPass(*os));
        break;
    case codegen::ASM:
        break;
    case codegen::OBJ:
        cgft = llvm::TargetMachine::CGFT_ObjectFile;
        break;
    default:
        // screem
        break;
    }

    functionPasses->doInitialization();
    for (llvm::Module::iterator I = llvmModule().begin(),
            E = llvmModule().end(); I != E; ++I)
        if (!I->isDeclaration())
            functionPasses->run(*I);
    functionPasses->doFinalization();

    modulePasses->run(llvmModule());

    if (codegenPasses) {
        formattedOS.setStream(*os, llvm::formatted_raw_ostream::PRESERVE_STREAM);
        if (targetMachine()->addPassesToEmitFile(*codegenPasses, formattedOS, cgft)) {
            std::cout << "pass fail";
        }
        codegenPasses->run(llvmModule());
    }
}
Exemplo n.º 4
0
    // GenerateMachineCode may modify the Module object passed in. Should we clone it first?
    void GenerateMachineCode(llvm::raw_ostream& os, IRModuleEmitter& moduleEmitter, OutputFileType fileType, const MachineCodeOutputOptions& ellOptions)
    {
        llvm::Module& module = *(moduleEmitter.GetLLVMModule());

        llvm::LLVMContext context;
        context.setDiscardValueNames(false); // Don't throw away names of non-global values

        // Verify module if requested
        if (ellOptions.verifyModule && llvm::verifyModule(module))
        {
            throw EmitterException(EmitterError::unexpected, "Module verification failed");
        }

        // Set the triple for the module, and retrieve it as a Triple object
        auto targetTripleStr = ellOptions.targetDevice.triple.empty() ? llvm::sys::getDefaultTargetTriple() : ellOptions.targetDevice.triple;
        module.setTargetTriple(llvm::Triple::normalize(targetTripleStr));
        llvm::Triple targetTriple{ module.getTargetTriple() };

        // Get the target-specific parser. Note that targetTriple can be modified by lookupTarget.
        std::string error;
        const llvm::Target* target = llvm::TargetRegistry::lookupTarget(ellOptions.targetDevice.architecture, targetTriple, error);
        if (!target)
        {
            throw EmitterException(EmitterError::unexpected, std::string("Couldn't create target ") + error);
        }

        llvm::TargetOptions targetOptions = MakeTargetOptions();
        targetOptions.MCOptions.AsmVerbose = ellOptions.verboseOutput;
        targetOptions.FloatABIType = ellOptions.floatABI;

        llvm::Reloc::Model relocModel = llvm::Reloc::Static;
        llvm::CodeModel::Model codeModel = llvm::CodeModel::Default;

        std::unique_ptr<llvm::TargetMachine> targetMachine(target->createTargetMachine(targetTriple.getTriple(),
                                                                                       ellOptions.targetDevice.cpu,
                                                                                       ellOptions.targetDevice.features,
                                                                                       targetOptions,
                                                                                       relocModel,
                                                                                       codeModel,
                                                                                       ellOptions.optimizationLevel));

        if (!targetMachine)
        {
            throw EmitterException(EmitterError::unexpected, "Unable to allocate target machine");
        }

        // Build up all of the passes that we want to apply to the module
        llvm::legacy::PassManager passManager;

        // Get a targetLibraryInfo describing the library functions available for this triple,
        // and any special processing we might want to do. For instance, if we want to
        // disable all builtin library functions, do this: `targetLibraryInfo.disableAllFunctions();`
        llvm::TargetLibraryInfoImpl targetLibraryInfo(llvm::Triple(module.getTargetTriple()));

        // ...and add it to the pass manager, so various optimizations can be done
        passManager.add(new llvm::TargetLibraryInfoWrapperPass(targetLibraryInfo));

        // Set the data layout of the module to match the target machine
        module.setDataLayout(targetMachine->createDataLayout());

        // Override function attributes based on cpu and features
        if (ellOptions.targetDevice.cpu != "")
        {
            SetFunctionAttributes(ellOptions.targetDevice.cpu, ellOptions.targetDevice.features, module);
        }

        // Set up passes to emit code to a memory stream
        llvm::SmallVector<char, 0> buffer;
        llvm::raw_svector_ostream bufferedStream(buffer);
        if (targetMachine->addPassesToEmitFile(passManager, bufferedStream, fileType, ellOptions.verifyModule, nullptr, nullptr, nullptr, nullptr))
        {
            throw EmitterException(EmitterError::unexpected, "target does not support generation of this file type!");
        }

        // Finally, run the passes to emit code to the straem
        passManager.run(module); // run() returns a bool indicating if the module was modified (true if it was)

        if (moduleEmitter.GetDiagnosticHandler().HadError())
        {
            throw EmitterException(EmitterError::unexpected, "Error compiling module");
        }

        // Write memory buffer to our output stream
        os << buffer;
    }
Exemplo n.º 5
0
	VirtualMachine::VirtualMachine(llvm::LLVMContext &context, const VirtualMachineOptions &opts)
     :  context(context), options(opts)
	{
#ifdef USE_ALL_TARGETS
        // Initialize all targets first
        llvm::InitializeAllTargets();
        llvm::InitializeAllTargetMCs();
        llvm::InitializeAllAsmPrinters();
        llvm::InitializeAllAsmParsers();
#else
        // Initialize the native target first
        llvm::InitializeNativeTarget();
        llvm::InitializeNativeTargetAsmPrinter();
#endif

        // Use the default target when no specified.
        if(options.Triple.empty())
            options.Triple = llvm::sys::getDefaultTargetTriple();
        triple.setTriple(options.Triple);

        // Lookup the the requested target.
        std::string error;
        target = llvm::TargetRegistry::lookupTarget(options.Triple, error);
        if(!target)
            throw VirtualMachineException("Failed to get target for " + options.Triple);

        // Create the target machine to get data about the target.
        std::auto_ptr<llvm::TargetMachine>
            targetMachine(target->createTargetMachine(options.Triple, options.Cpu, options.FeatureString, options.TargetOptions));
        if(!targetMachine.get())
            throw VirtualMachineException("Failed to create a target machine for " + options.Triple);

        // Copy the target data of the machine.
        targetData = new llvm::TargetData(*targetMachine->getTargetData());
        
        // Create the type data.
        dataImpl = new _VirtualMachineDataImpl(this, context, targetData);

        // Initialize to null some variables.
		executionEngine = NULL;
		runtimeModule = NULL;

        // Base classes.
		objectClass = NULL;
        typeClass = NULL;
		stringClass = NULL;
        closureClass = NULL;
        arrayClass = NULL;
        valueTypeClass = NULL;
        enumClass = NULL;
        delegateClass = NULL;

        // Special attributes.
        threadStaticAttribute = NULL;
        chelaIntrinsicAttribute = NULL;

        // Kernel data holders
        streamHolderClass = NULL;
        streamHolder1DClass = NULL;
        streamHolder2DClass = NULL;
        streamHolder3DClass = NULL;
        uniformHolderClass = NULL;

        // Reflection info.
        assemblyClass = NULL;
        constructorInfoClass = NULL;
        eventInfoClass = NULL;
        fieldInfoClass = NULL;
        memberInfoClass = NULL;
        methodInfoClass = NULL;
        parameterInfoClass = NULL;
        propertyInfoClass = NULL;

        // Memory management.
		unmanagedAlloc = NULL;
		unmanagedAllocArray = NULL;
		unmanagedFree = NULL;
		unmanagedFreeArray = NULL;
		managedAlloc = NULL;
        addReference = NULL;
        releaseReference = NULL;

        // Casting.
        objectDownCast = NULL;
        ifaceDownCast = NULL;
        ifaceCrossCast = NULL;
        checkCast = NULL;

        // Type checking.
        isRefType = NULL;

        // Exception handling.
        ehPersonality = NULL;
        ehThrow = NULL;
        ehRead = NULL;

        // Implicit checks.
        throwNull = NULL;
        throwBound = NULL;

        // Kernel binder helpers.
        computeIsCpu = NULL;
        computeCpuBind = NULL;
        computeBind = NULL;

        // Initialize the sys layer.
        InitSysLayer();
	}
Exemplo n.º 6
0
		llvm::DataLayout InternalContext::dataLayout() const {
			return targetMachine().createDataLayout();
		}
Exemplo n.º 7
0
Arquivo: main.cpp Projeto: mystor/cppi
int main(int argc, const char * argv[]) {
    // Usage Message (TODO: Improve)
    if (argc < 3) {
        std::cerr << "Usage: " << argv[0] << " <FileName>\n"
                  << "Compiles the file given by <FileName>\n";
        return 1;
    }

    // Read in the file passed as the first argument
    std::ifstream fileStream;
    fileStream.open(argv[1]);

    // We'll output to the file passed in as the second argument
    std::error_code ec;
    auto openflags = llvm::sys::fs::F_None;
    auto out = std::make_unique<llvm::tool_output_file>(argv[2], ec, openflags);

    if (ec) {
        std::cerr << argv[0] << ": " << ec.message() << "\n";
        return 1;
    }

    // Parse it!
    auto lex = Lexer(&fileStream);
    auto stmts = parse(&lex);

    // std::cout << "Result of parsing: \n";
    // for (auto &stmt : stmts) {
    //     std::cout << *stmt << ";\n";
    // }

    auto prgm = Program();
    prgm.addItems(stmts);
    prgm.finalize();

    auto mod = prgm.module;

    /* DEBUG */
    // mod->dump();

    llvm::InitializeNativeTarget();
    llvm::InitializeNativeTargetAsmPrinter();
    llvm::InitializeNativeTargetAsmParser();

    llvm::PassRegistry *registry = llvm::PassRegistry::getPassRegistry();
    llvm::initializeCore(*registry);
    llvm::initializeCodeGen(*registry);
    llvm::initializeLoopStrengthReducePass(*registry);
    llvm::initializeLowerIntrinsicsPass(*registry);
    llvm::initializeUnreachableBlockElimPass(*registry);

    llvm::Triple targetTriple(mod->getTargetTriple());
    if (targetTriple.getTriple().empty()) {
        targetTriple.setTriple(llvm::sys::getDefaultTargetTriple());
    }

    std::cout << "Target Triple: " << targetTriple.getTriple() << "\n";

    std::string error;
    const llvm::Target *target = llvm::TargetRegistry::lookupTarget("", targetTriple, error);
    if (! target) {
        std::cerr << argv[0] << ": " << error;
        return 1;
    }

    auto optLvl = llvm::CodeGenOpt::Default;
    switch ('0') { // TEmporary
    default:
        std::cerr << argv[0] << ": invalid optimization level.\n";
        return 1;
    case ' ': break;
    case '0': optLvl = llvm::CodeGenOpt::None; break;
    case '1': optLvl = llvm::CodeGenOpt::Less; break;
    case '2': optLvl = llvm::CodeGenOpt::Default; break;
    case '3': optLvl = llvm::CodeGenOpt::Aggressive; break;
    }

    // llvm::TargetOptions options;
    // TODO: llc line 268

    std::unique_ptr<llvm::TargetMachine> targetMachine(target->createTargetMachine(targetTriple.getTriple(),
                                                                                   llvm::sys::getHostCPUName(),
                                                                                   "",
                                                                                   llvm::TargetOptions(),
                                                                                   llvm::Reloc::Default,
                                                                                   llvm::CodeModel::Default,
                                                                                   optLvl));
    assert(targetMachine && "Could not allocate target machine!");

    llvm::PassManager passmanager;
    llvm::TargetLibraryInfo *TLI = new llvm::TargetLibraryInfo(targetTriple);
    passmanager.add(TLI);

    if (const llvm::DataLayout *datalayout = targetMachine->getSubtargetImpl()->getDataLayout())
        mod->setDataLayout(datalayout);

    llvm::formatted_raw_ostream ostream(out->os());

    // Ask the target to add backend passes as necessary.
    if (targetMachine->addPassesToEmitFile(passmanager, ostream, llvm::TargetMachine::CGFT_ObjectFile)) {
        std::cerr << argv[0] << ": target does not support generation of this"
                  << " file type!\n";
        return 1;
    }

    passmanager.run(*mod);

    out->keep();

    return 0;
}