2 #include "llvm/Bitcode/BitcodeReader.h"
3 #include "llvm/Bitcode/BitcodeWriter.h"
5 #include "llvm/Bitcode/ReaderWriter.h"
8 #include "llvm/IR/Function.h"
9 #include "llvm/IR/GlobalVariable.h"
10 #include "llvm/IR/LLVMContext.h"
11 #include "llvm/IR/Module.h"
12 #include "llvm/Support/CommandLine.h"
13 #include "llvm/Support/ManagedStatic.h"
14 #include "llvm/Support/MemoryBuffer.h"
15 #include "llvm/Support/FileSystem.h"
16 #include "llvm/Support/raw_ostream.h"
17 #include "llvm/Support/ErrorOr.h"
18 #include "llvm/Support/ToolOutputFile.h"
19 #include "llvm/Config/llvm-config.h"
21 #include <system_error>
25 static cl::opt
<std::string
>
26 InputFilename(cl::Positional
, cl::desc("<input bitcode>"), cl::init("-"));
28 static cl::opt
<std::string
>
29 OutputFilename("o", cl::desc("Output filename"),
30 cl::value_desc("filename"));
32 int main(int argc
, char **argv
) {
34 llvm_shutdown_obj Y
; // Call llvm_shutdown() on exit.
36 cl::ParseCommandLineOptions(argc
, argv
, "libclc builtin preparation tool\n");
38 std::string ErrorMessage
;
42 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> BufferOrErr
=
43 MemoryBuffer::getFile(InputFilename
);
44 if (std::error_code ec
= BufferOrErr
.getError()) {
45 ErrorMessage
= ec
.message();
47 std::unique_ptr
<MemoryBuffer
> &BufferPtr
= BufferOrErr
.get();
48 ErrorOr
<std::unique_ptr
<Module
>> ModuleOrErr
=
49 #if HAVE_LLVM > 0x0390
50 expectedToErrorOrAndEmitErrors(Context
,
51 parseBitcodeFile(BufferPtr
.get()->getMemBufferRef(), Context
));
53 parseBitcodeFile(BufferPtr
.get()->getMemBufferRef(), Context
);
55 if (std::error_code ec
= ModuleOrErr
.getError())
56 ErrorMessage
= ec
.message();
58 M
= ModuleOrErr
.get().release();
63 errs() << argv
[0] << ": ";
64 if (ErrorMessage
.size())
65 errs() << ErrorMessage
<< "\n";
67 errs() << "bitcode didn't read correctly.\n";
71 // Strip the OpenCL version metadata. There are a lot of linked
72 // modules in the library build, each spamming the same
73 // version. This may also report a different version than the user
74 // program is using. This should probably be uniqued when linking.
75 if (NamedMDNode
*OCLVersion
= M
->getNamedMetadata("opencl.ocl.version"))
76 M
->eraseNamedMetadata(OCLVersion
);
78 // Set linkage of every external definition to linkonce_odr.
79 for (Module::iterator i
= M
->begin(), e
= M
->end(); i
!= e
; ++i
) {
80 if (!i
->isDeclaration() && i
->getLinkage() == GlobalValue::ExternalLinkage
)
81 i
->setLinkage(GlobalValue::LinkOnceODRLinkage
);
84 for (Module::global_iterator i
= M
->global_begin(), e
= M
->global_end();
86 if (!i
->isDeclaration() && i
->getLinkage() == GlobalValue::ExternalLinkage
)
87 i
->setLinkage(GlobalValue::LinkOnceODRLinkage
);
90 if (OutputFilename
.empty()) {
91 errs() << "no output file\n";
96 #if HAVE_LLVM >= 0x0600
97 std::unique_ptr
<ToolOutputFile
> Out(
98 new ToolOutputFile(OutputFilename
, EC
, sys::fs::OF_None
));
100 std::unique_ptr
<tool_output_file
> Out(
101 new tool_output_file(OutputFilename
, EC
, sys::fs::OF_None
));
104 errs() << EC
.message() << '\n';
108 #if HAVE_LLVM >= 0x0700
109 WriteBitcodeToFile(*M
, Out
->os());
111 WriteBitcodeToFile(M
, Out
->os());