// Encase the Bitcode in a wrapper containing RS version information. void Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) { bcinfo::AndroidBitcodeWrapper wrapper; size_t actualWrapperLen = bcinfo::writeAndroidBitcodeWrapper( &wrapper, Bitcode.str().length(), getTargetAPI(), SlangVersion::CURRENT, mCodeGenOpts.OptimizationLevel); slangAssert(actualWrapperLen > 0); // Write out the bitcode wrapper. FormattedOutStream.write(reinterpret_cast<char*>(&wrapper), actualWrapperLen); // Write out the actual encoded bitcode. FormattedOutStream << Bitcode.str(); }
// Encase the Bitcode in a wrapper containing RS version information. void Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) { struct bcinfo::BCWrapperHeader header; header.Magic = 0x0B17C0DE; header.Version = 0; header.BitcodeOffset = sizeof(header); header.BitcodeSize = Bitcode.str().length(); header.HeaderVersion = 0; header.TargetAPI = getTargetAPI(); // Write out the bitcode wrapper. FormattedOutStream.write((const char*) &header, sizeof(header)); // Write out the actual encoded bitcode. FormattedOutStream << Bitcode.str(); return; }
void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) { HandleTranslationUnitPre(Ctx); mGen->HandleTranslationUnit(Ctx); // Here, we complete a translation unit (whole translation unit is now in LLVM // IR). Now, interact with LLVM backend to generate actual machine code (asm // or machine code, whatever.) // Silently ignore if we weren't initialized for some reason. if (!mpModule) return; llvm::Module *M = mGen->ReleaseModule(); if (!M) { // The module has been released by IR gen on failures, do not double free. mpModule = NULL; return; } slangAssert(mpModule == M && "Unexpected module change during LLVM IR generation"); // Insert #pragma information into metadata section of module if (!mPragmas->empty()) { llvm::NamedMDNode *PragmaMetadata = mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName); for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end(); I != E; I++) { llvm::SmallVector<llvm::Value*, 2> Pragma; // Name goes first Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first)); // And then value Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second)); // Create MDNode and insert into PragmaMetadata PragmaMetadata->addOperand( llvm::MDNode::get(mLLVMContext, Pragma)); } } HandleTranslationUnitPost(mpModule); // Create passes for optimization and code emission // Create and run per-function passes CreateFunctionPasses(); if (mPerFunctionPasses) { mPerFunctionPasses->doInitialization(); for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end(); I != E; I++) if (!I->isDeclaration()) mPerFunctionPasses->run(*I); mPerFunctionPasses->doFinalization(); } // Create and run module passes CreateModulePasses(); if (mPerModulePasses) mPerModulePasses->run(*mpModule); switch (mOT) { case Slang::OT_Assembly: case Slang::OT_Object: { if (!CreateCodeGenPasses()) return; mCodeGenPasses->doInitialization(); for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end(); I != E; I++) if (!I->isDeclaration()) mCodeGenPasses->run(*I); mCodeGenPasses->doFinalization(); break; } case Slang::OT_LLVMAssembly: { llvm::PassManager *LLEmitPM = new llvm::PassManager(); LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream)); LLEmitPM->run(*mpModule); break; } case Slang::OT_Bitcode: { llvm::PassManager *BCEmitPM = new llvm::PassManager(); std::string BCStr; llvm::raw_string_ostream Bitcode(BCStr); unsigned int TargetAPI = getTargetAPI(); switch (TargetAPI) { case SLANG_HC_TARGET_API: case SLANG_HC_MR1_TARGET_API: case SLANG_HC_MR2_TARGET_API: { // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter BCEmitPM->add(llvm_2_9::createBitcodeWriterPass(Bitcode)); break; } case SLANG_ICS_TARGET_API: case SLANG_ICS_MR1_TARGET_API: { // ICS targets must use the LLVM 2.9_func BitcodeWriter BCEmitPM->add(llvm_2_9_func::createBitcodeWriterPass(Bitcode)); break; } default: { if (TargetAPI < SLANG_MINIMUM_TARGET_API || TargetAPI > SLANG_MAXIMUM_TARGET_API) { slangAssert(false && "Invalid target API value"); } // Switch to the 3.2 BitcodeWriter by default, and don't use // LLVM's included BitcodeWriter at all (for now). BCEmitPM->add(llvm_3_2::createBitcodeWriterPass(Bitcode)); //BCEmitPM->add(llvm::createBitcodeWriterPass(Bitcode)); break; } } BCEmitPM->run(*mpModule); WrapBitcode(Bitcode); break; } case Slang::OT_Nothing: { return; } default: { slangAssert(false && "Unknown output type"); } } FormattedOutStream.flush(); return; }