xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
106c3fb27SDimitry Andric //===- EmbedBitcodePass.cpp - Pass that embeds the bitcode into a global---===//
206c3fb27SDimitry Andric //
306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric //
706c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric 
906c3fb27SDimitry Andric #include "llvm/Transforms/IPO/EmbedBitcodePass.h"
10*7a6dacacSDimitry Andric #include "llvm/Bitcode/BitcodeWriter.h"
11*7a6dacacSDimitry Andric #include "llvm/Bitcode/BitcodeWriterPass.h"
1206c3fb27SDimitry Andric #include "llvm/IR/PassManager.h"
1306c3fb27SDimitry Andric #include "llvm/Pass.h"
1406c3fb27SDimitry Andric #include "llvm/Support/ErrorHandling.h"
1506c3fb27SDimitry Andric #include "llvm/Support/MemoryBufferRef.h"
1606c3fb27SDimitry Andric #include "llvm/Support/raw_ostream.h"
1706c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
1806c3fb27SDimitry Andric #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
1906c3fb27SDimitry Andric #include "llvm/Transforms/Utils/ModuleUtils.h"
2006c3fb27SDimitry Andric 
21*7a6dacacSDimitry Andric #include <memory>
2206c3fb27SDimitry Andric #include <string>
2306c3fb27SDimitry Andric 
2406c3fb27SDimitry Andric using namespace llvm;
2506c3fb27SDimitry Andric 
run(Module & M,ModuleAnalysisManager & AM)2606c3fb27SDimitry Andric PreservedAnalyses EmbedBitcodePass::run(Module &M, ModuleAnalysisManager &AM) {
2706c3fb27SDimitry Andric   if (M.getGlobalVariable("llvm.embedded.module", /*AllowInternal=*/true))
2806c3fb27SDimitry Andric     report_fatal_error("Can only embed the module once",
2906c3fb27SDimitry Andric                        /*gen_crash_diag=*/false);
3006c3fb27SDimitry Andric 
3106c3fb27SDimitry Andric   Triple T(M.getTargetTriple());
3206c3fb27SDimitry Andric   if (T.getObjectFormat() != Triple::ELF)
3306c3fb27SDimitry Andric     report_fatal_error(
3406c3fb27SDimitry Andric         "EmbedBitcode pass currently only supports ELF object format",
3506c3fb27SDimitry Andric         /*gen_crash_diag=*/false);
36*7a6dacacSDimitry Andric 
3706c3fb27SDimitry Andric   std::string Data;
3806c3fb27SDimitry Andric   raw_string_ostream OS(Data);
39*7a6dacacSDimitry Andric   if (IsThinLTO)
405f757f3fSDimitry Andric     ThinLTOBitcodeWriterPass(OS, /*ThinLinkOS=*/nullptr).run(M, AM);
41*7a6dacacSDimitry Andric   else
42*7a6dacacSDimitry Andric     BitcodeWriterPass(OS, /*ShouldPreserveUseListOrder=*/false, EmitLTOSummary)
43*7a6dacacSDimitry Andric         .run(M, AM);
44*7a6dacacSDimitry Andric 
4506c3fb27SDimitry Andric   embedBufferInModule(M, MemoryBufferRef(Data, "ModuleData"), ".llvm.lto");
46*7a6dacacSDimitry Andric 
4706c3fb27SDimitry Andric   return PreservedAnalyses::all();
4806c3fb27SDimitry Andric }
49