2 #include "llvm/Bitcode/BitcodeReader.h"
3 #include "llvm/Bitcode/BitcodeWriter.h"
5 #include "llvm/Bitcode/ReaderWriter.h"
8 #include "llvm/Config/llvm-config.h"
9 #include "llvm/IR/Function.h"
10 #include "llvm/IR/GlobalVariable.h"
11 #include "llvm/IR/LLVMContext.h"
12 #include "llvm/IR/Module.h"
13 #include "llvm/IRReader/IRReader.h"
14 #include "llvm/Support/CommandLine.h"
15 #include "llvm/Support/ErrorOr.h"
16 #include "llvm/Support/FileSystem.h"
17 #include "llvm/Support/ManagedStatic.h"
18 #include "llvm/Support/MemoryBuffer.h"
19 #include "llvm/Support/SourceMgr.h"
20 #include "llvm/Support/ToolOutputFile.h"
21 #include "llvm/Support/raw_ostream.h"
23 #include <system_error>
27 static ExitOnError ExitOnErr
;
29 static cl::opt
<std::string
>
30 InputFilename(cl::Positional
, cl::desc("<input bitcode>"), cl::init("-"));
32 static cl::opt
<std::string
>
33 OutputFilename("o", cl::desc("Output filename"),
34 cl::value_desc("filename"));
36 static cl::opt
<bool> TextualOut("S", cl::desc("Emit LLVM textual assembly"),
39 int main(int argc
, char **argv
) {
41 llvm_shutdown_obj Y
; // Call llvm_shutdown() on exit.
43 cl::ParseCommandLineOptions(argc
, argv
, "libclc builtin preparation tool\n");
45 std::string ErrorMessage
;
49 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> BufferOrErr
=
50 MemoryBuffer::getFile(InputFilename
);
51 if (std::error_code ec
= BufferOrErr
.getError()) {
52 ErrorMessage
= ec
.message();
54 std::unique_ptr
<MemoryBuffer
> &BufferPtr
= BufferOrErr
.get();
56 std::unique_ptr
<llvm::Module
> MPtr
=
57 #if HAVE_LLVM > 0x0390
58 ExitOnErr(Expected
<std::unique_ptr
<llvm::Module
>>(
59 parseIR(BufferPtr
.get()->getMemBufferRef(), Err
, Context
)));
61 parseIR(BufferPtr
.get()->getMemBufferRef(), Err
, Context
);
68 errs() << argv
[0] << ": ";
69 if (ErrorMessage
.size())
70 errs() << ErrorMessage
<< "\n";
72 errs() << "bitcode didn't read correctly.\n";
76 // Strip the OpenCL version metadata. There are a lot of linked
77 // modules in the library build, each spamming the same
78 // version. This may also report a different version than the user
79 // program is using. This should probably be uniqued when linking.
80 if (NamedMDNode
*OCLVersion
= M
->getNamedMetadata("opencl.ocl.version"))
81 M
->eraseNamedMetadata(OCLVersion
);
83 // Set linkage of every external definition to linkonce_odr.
84 for (Module::iterator i
= M
->begin(), e
= M
->end(); i
!= e
; ++i
) {
85 if (!i
->isDeclaration() && i
->getLinkage() == GlobalValue::ExternalLinkage
)
86 i
->setLinkage(GlobalValue::LinkOnceODRLinkage
);
89 for (Module::global_iterator i
= M
->global_begin(), e
= M
->global_end();
91 if (!i
->isDeclaration() && i
->getLinkage() == GlobalValue::ExternalLinkage
)
92 i
->setLinkage(GlobalValue::LinkOnceODRLinkage
);
95 if (OutputFilename
.empty()) {
96 errs() << "no output file\n";
101 #if HAVE_LLVM >= 0x0600
102 std::unique_ptr
<ToolOutputFile
> Out(
103 new ToolOutputFile(OutputFilename
, EC
, sys::fs::OF_None
));
105 std::unique_ptr
<tool_output_file
> Out(
106 new tool_output_file(OutputFilename
, EC
, sys::fs::OF_None
));
109 errs() << EC
.message() << '\n';
114 M
->print(Out
->os(), nullptr, true);
116 #if HAVE_LLVM >= 0x0700
117 WriteBitcodeToFile(*M
, Out
->os());
119 WriteBitcodeToFile(M
, Out
->os());