blob: 2aefcc9248af08b9d1cf035ea929a4bfe2e8c706 [file] [log] [blame]
Peter Collingbourned5395fb2012-01-08 22:09:58 +00001#include "llvm/Bitcode/ReaderWriter.h"
Tom Stellard976577e2013-06-26 18:20:32 +00002#include "llvm/IR/Function.h"
3#include "llvm/IR/GlobalVariable.h"
4#include "llvm/IR/LLVMContext.h"
5#include "llvm/IR/Module.h"
Peter Collingbourned5395fb2012-01-08 22:09:58 +00006#include "llvm/Support/CommandLine.h"
7#include "llvm/Support/ManagedStatic.h"
8#include "llvm/Support/MemoryBuffer.h"
Tom Stellard98dccb12014-04-30 18:35:20 +00009#include "llvm/Support/FileSystem.h"
Peter Collingbourned5395fb2012-01-08 22:09:58 +000010#include "llvm/Support/raw_ostream.h"
Tom Stellard8a63b152014-01-20 20:28:48 +000011#include "llvm/Support/ErrorOr.h"
Peter Collingbourned5395fb2012-01-08 22:09:58 +000012#include "llvm/Support/ToolOutputFile.h"
Niels Ole Salscheider109ce692014-08-22 22:24:28 +000013#include "llvm/Config/llvm-config.h"
Peter Collingbourned5395fb2012-01-08 22:09:58 +000014
Jeroen Ketemad253e662014-06-21 09:20:31 +000015#include <system_error>
16
Tom Stellard4957e402015-06-24 17:03:50 +000017#define LLVM_360 \
18 (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR == 6)
19
20
Jeroen Ketemad253e662014-06-21 09:20:31 +000021using namespace llvm;
22
Peter Collingbourned5395fb2012-01-08 22:09:58 +000023static cl::opt<std::string>
24InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
25
26static cl::opt<std::string>
27OutputFilename("o", cl::desc("Output filename"),
28 cl::value_desc("filename"));
29
30int main(int argc, char **argv) {
31 LLVMContext &Context = getGlobalContext();
32 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
33
34 cl::ParseCommandLineOptions(argc, argv, "libclc builtin preparation tool\n");
35
36 std::string ErrorMessage;
Jeroen Ketema2697d2a2015-06-27 12:35:54 +000037 Module *M = nullptr;
Peter Collingbourned5395fb2012-01-08 22:09:58 +000038
39 {
Tom Stellard8d92c392014-07-07 17:46:45 +000040 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
41 MemoryBuffer::getFile(InputFilename);
42 std::unique_ptr<MemoryBuffer> &BufferPtr = BufferOrErr.get();
43 if (std::error_code ec = BufferOrErr.getError())
Peter Collingbourned5395fb2012-01-08 22:09:58 +000044 ErrorMessage = ec.message();
Tom Stellard8a63b152014-01-20 20:28:48 +000045 else {
Tom Stellard4957e402015-06-24 17:03:50 +000046#if LLVM_360
47 ErrorOr<Module *>
48#else
49 ErrorOr<std::unique_ptr<Module>>
50#endif
51 ModuleOrErr =
52 parseBitcodeFile(BufferPtr.get()->getMemBufferRef(), Context);
Tom Stellard1d770712014-12-31 15:27:53 +000053 if (std::error_code ec = ModuleOrErr.getError())
Tom Stellard8a63b152014-01-20 20:28:48 +000054 ErrorMessage = ec.message();
Tom Stellard4957e402015-06-24 17:03:50 +000055#if LLVM_360
56 M = ModuleOrErr.get().get();
57#else
58 M = ModuleOrErr.get().release();
59#endif
Tom Stellard8a63b152014-01-20 20:28:48 +000060 }
Peter Collingbourned5395fb2012-01-08 22:09:58 +000061 }
62
Tom Stellard4957e402015-06-24 17:03:50 +000063 if (!M) {
Peter Collingbourned5395fb2012-01-08 22:09:58 +000064 errs() << argv[0] << ": ";
65 if (ErrorMessage.size())
66 errs() << ErrorMessage << "\n";
67 else
68 errs() << "bitcode didn't read correctly.\n";
69 return 1;
70 }
71
72 // Set linkage of every external definition to linkonce_odr.
73 for (Module::iterator i = M->begin(), e = M->end(); i != e; ++i) {
74 if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage)
75 i->setLinkage(GlobalValue::LinkOnceODRLinkage);
76 }
77
78 for (Module::global_iterator i = M->global_begin(), e = M->global_end();
79 i != e; ++i) {
80 if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage)
81 i->setLinkage(GlobalValue::LinkOnceODRLinkage);
82 }
83
84 if (OutputFilename.empty()) {
85 errs() << "no output file\n";
86 return 1;
87 }
88
Michel Danzera10b4922014-08-28 06:19:33 +000089 std::error_code EC;
Tom Stellard1d770712014-12-31 15:27:53 +000090 std::unique_ptr<tool_output_file> Out
Michel Danzera10b4922014-08-28 06:19:33 +000091 (new tool_output_file(OutputFilename, EC, sys::fs::F_None));
92 if (EC) {
93 errs() << EC.message() << '\n';
94 exit(1);
95 }
Peter Collingbourned5395fb2012-01-08 22:09:58 +000096
Tom Stellard4957e402015-06-24 17:03:50 +000097 WriteBitcodeToFile(M, Out->os());
Peter Collingbourned5395fb2012-01-08 22:09:58 +000098
99 // Declare success.
100 Out->keep();
101 return 0;
102}
103