e10ea5f925f439fcea129c5193207c808ab67b8b
[oota-llvm.git] / tools / lto2 / LTOModule.cpp
1 //===-LTOModule.cpp - LLVM Link Time Optimizer ----------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the Link Time Optimization library. This library is 
11 // intended to be used by linker to optimize code at link time.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Module.h"
16 #include "llvm/PassManager.h"
17 #include "llvm/Linker.h"
18 #include "llvm/Constants.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/ModuleProvider.h"
21 #include "llvm/Bitcode/ReaderWriter.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/FileUtilities.h"
24 #include "llvm/Support/SystemUtils.h"
25 #include "llvm/Support/Mangler.h"
26 #include "llvm/Support/MemoryBuffer.h"
27 #include "llvm/System/Program.h"
28 #include "llvm/System/Path.h"
29 #include "llvm/System/Signals.h"
30 #include "llvm/Target/SubtargetFeature.h"
31 #include "llvm/Target/TargetOptions.h"
32 #include "llvm/Target/TargetData.h"
33 #include "llvm/Target/TargetMachine.h"
34 #include "llvm/Target/TargetMachineRegistry.h"
35 #include "llvm/Target/TargetAsmInfo.h"
36 #include "llvm/Transforms/IPO.h"
37 #include "llvm/Transforms/Scalar.h"
38 #include "llvm/Analysis/LoadValueNumbering.h"
39 #include "llvm/Support/MathExtras.h"
40
41 #include "LTOModule.h"
42
43 #include <fstream>
44
45 using namespace llvm;
46
47 bool LTOModule::isBitcodeFile(const void* mem, size_t length)
48 {
49     return ( llvm::sys::IdentifyFileType((char*)mem, length) 
50                                             == llvm::sys::Bitcode_FileType );
51 }
52
53 bool LTOModule::isBitcodeFile(const char* path)
54 {
55     return llvm::sys::Path(path).isBitcodeFile();
56 }
57
58 bool LTOModule::isBitcodeFileForTarget(const void* mem, 
59                                     size_t length, const char* triplePrefix) 
60 {
61     bool result = false;
62     MemoryBuffer* buffer;
63     buffer = MemoryBuffer::getMemBuffer((char*)mem, (char*)mem+length);
64     if ( buffer != NULL ) {
65         ModuleProvider* mp = getBitcodeModuleProvider(buffer);
66         if ( mp != NULL ) {
67             std::string actualTarget = mp->getModule()->getTargetTriple();
68             if  ( strncmp(actualTarget.c_str(), triplePrefix, 
69                                     strlen(triplePrefix)) == 0) {
70                 result = true;
71             }
72             //  mp destructor will delete buffer
73             delete mp;
74         }
75         else {
76             // if getBitcodeModuleProvider failed, we need to delete buffer
77             delete buffer;
78         }
79     }
80     return result;
81 }
82
83 bool LTOModule::isBitcodeFileForTarget(const char* path,
84                                                 const char* triplePrefix) 
85 {
86     bool result = false;
87     MemoryBuffer* buffer;
88     buffer = MemoryBuffer::getFile(path, strlen(path));
89     if ( buffer != NULL ) {
90         ModuleProvider* mp = getBitcodeModuleProvider(buffer);
91         if ( mp != NULL ) {
92             std::string actualTarget = mp->getModule()->getTargetTriple();
93             if  ( strncmp(actualTarget.c_str(), triplePrefix, 
94                                     strlen(triplePrefix)) == 0) {
95                 result = true;
96             }
97             //  mp destructor will delete buffer
98             delete mp;
99         }
100         else {
101             // if getBitcodeModuleProvider failed, we need to delete buffer
102             delete buffer;
103         }
104     }
105     return result;
106 }
107
108
109 LTOModule::LTOModule(Module* m, TargetMachine* t) 
110  : _module(m), _target(t), _symbolsParsed(false)
111 {
112 }
113
114 LTOModule::~LTOModule()
115 {
116     delete _module;
117     if ( _target != NULL )
118         delete _target;
119 }
120
121
122 LTOModule* LTOModule::makeLTOModule(const char* path, std::string& errMsg)
123 {
124     MemoryBuffer* buffer = MemoryBuffer::getFile(path, strlen(path));
125     if ( buffer != NULL ) {
126         Module* m = ParseBitcodeFile(buffer, &errMsg);
127         delete buffer;
128         if ( m != NULL ) {
129             const TargetMachineRegistry::entry* march = 
130               TargetMachineRegistry::getClosestStaticTargetForModule(*m, errMsg);
131             if ( march != NULL ) {
132                 std::string features;
133                 TargetMachine*    target = march->CtorFn(*m, features);
134                 return new LTOModule(m, target);
135             }
136         }
137     }
138     return NULL;
139 }
140
141 LTOModule* LTOModule::makeLTOModule(const void* mem, size_t length, 
142                                                         std::string& errMsg)
143 {
144     MemoryBuffer* buffer;
145     buffer = MemoryBuffer::getMemBuffer((char*)mem, (char*)mem+length);
146     if ( buffer != NULL ) {
147         Module* m = ParseBitcodeFile(buffer, &errMsg);
148         delete buffer;
149         if ( m != NULL ) {
150             const TargetMachineRegistry::entry* march = 
151              TargetMachineRegistry::getClosestStaticTargetForModule(*m, errMsg);
152             if ( march != NULL ) {
153                 std::string features;
154                 TargetMachine*    target = march->CtorFn(*m, features);
155                 return new LTOModule(m, target);
156             }
157         }
158     }
159     return NULL;
160 }
161
162
163 const char* LTOModule::getTargetTriple()
164 {
165     return _module->getTargetTriple().c_str();
166 }
167
168 void LTOModule::addDefinedSymbol(GlobalValue* def, Mangler &mangler, 
169                                 bool isFunction)
170 {    
171     const char* symbolName = ::strdup(mangler.getValueName(def).c_str());
172     
173     // set alignment part log2() can have rounding errors
174     uint32_t align = def->getAlignment();
175     uint32_t attr = align ? __builtin_ctz(def->getAlignment()) : 0;
176     
177     // set permissions part
178     if ( isFunction )
179         attr |= LTO_SYMBOL_PERMISSIONS_CODE;
180     else {
181         GlobalVariable* gv = dyn_cast<GlobalVariable>(def);
182         if ( (gv != NULL) && gv->isConstant() )
183             attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
184         else
185             attr |= LTO_SYMBOL_PERMISSIONS_DATA;
186     }
187     
188     // set definition part 
189     if ( def->hasWeakLinkage() || def->hasLinkOnceLinkage() ) {
190         // lvm bitcode does not differenciate between weak def data 
191         // and tentative definitions!
192         // HACK HACK HACK
193         // C++ does not use tentative definitions, but does use weak symbols
194         // so guess that anything that looks like a C++ symbol is weak and others
195         // are tentative definitions
196         if ( (strncmp(symbolName, "__Z", 3) == 0) )
197             attr |= LTO_SYMBOL_DEFINITION_WEAK;
198         else {
199             attr |= LTO_SYMBOL_DEFINITION_TENTATIVE;
200         }
201     }
202     else { 
203         attr |= LTO_SYMBOL_DEFINITION_REGULAR;
204     }
205     
206     // set scope part
207     if ( def->hasHiddenVisibility() )
208         attr |= LTO_SYMBOL_SCOPE_HIDDEN;
209     else if ( def->hasExternalLinkage() || def->hasWeakLinkage() )
210         attr |= LTO_SYMBOL_SCOPE_DEFAULT;
211     else
212         attr |= LTO_SYMBOL_SCOPE_INTERNAL;
213
214     // add to table of symbols
215     NameAndAttributes info;
216     info.name = symbolName;
217     info.attributes = (lto_symbol_attributes)attr;
218     _symbols.push_back(info);
219     _defines[info.name] = 1;
220 }
221
222
223 void LTOModule::addUndefinedSymbol(const char* name)
224 {    
225     // ignore all llvm.* symbols
226     if ( strncmp(name, "llvm.", 5) != 0 ) {
227         _undefines[name] = 1;
228     }
229 }
230
231
232
233 // Find exeternal symbols referenced by VALUE. This is a recursive function.
234 void LTOModule::findExternalRefs(Value* value, Mangler &mangler) {
235
236     if (GlobalValue* gv = dyn_cast<GlobalValue>(value)) {
237         if ( !gv->hasExternalLinkage() )
238             addUndefinedSymbol(mangler.getValueName(gv).c_str());
239     }
240
241     // GlobalValue, even with InternalLinkage type, may have operands with 
242     // ExternalLinkage type. Do not ignore these operands.
243     if (Constant* c = dyn_cast<Constant>(value)) {
244         // Handle ConstantExpr, ConstantStruct, ConstantArry etc..
245         for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i)
246             findExternalRefs(c->getOperand(i), mangler);
247     }
248 }
249
250
251 uint32_t LTOModule::getSymbolCount()
252 {
253     if ( !_symbolsParsed ) {
254         _symbolsParsed = true;
255         
256         // Use mangler to add GlobalPrefix to names to match linker names.
257         Mangler mangler(*_module, _target->getTargetAsmInfo()->getGlobalPrefix());
258
259         // add functions
260         for (Module::iterator f = _module->begin(); f != _module->end(); ++f) {
261             if ( f->isDeclaration() ) {
262                 addUndefinedSymbol(mangler.getValueName(f).c_str());
263             }
264             else {
265                 addDefinedSymbol(f, mangler, true);
266                 // add external symbols referenced by this function.
267                 for (Function::iterator b = f->begin(); b != f->end(); ++b) {
268                     for (BasicBlock::iterator i = b->begin(); 
269                                                         i != b->end(); ++i) {
270                         for (unsigned count = 0, total = i->getNumOperands(); 
271                                                     count != total; ++count) {
272                             findExternalRefs(i->getOperand(count), mangler);
273                         }
274                     }
275                 }
276             }
277         }
278         
279         // add data 
280         for (Module::global_iterator v = _module->global_begin(), 
281                                     e = _module->global_end(); v !=  e; ++v) {
282             if ( v->isDeclaration() ) {
283                 addUndefinedSymbol(mangler.getValueName(v).c_str());
284             }
285             else {
286                 addDefinedSymbol(v, mangler, false);
287                 // add external symbols referenced by this data
288                 for (unsigned count = 0, total = v->getNumOperands(); 
289                                                 count != total; ++count) {
290                     findExternalRefs(v->getOperand(count), mangler);
291                 }
292             }
293         }
294
295         // make symbols for all undefines
296         for (StringSet::iterator it=_undefines.begin(); 
297                                                 it != _undefines.end(); ++it) {
298             // if this symbol also has a definition, then don't make an undefine
299             // because it is a tentative definition
300             if ( _defines.find(it->getKeyData(), it->getKeyData()+it->getKeyLength()) == _defines.end() ) {
301                 NameAndAttributes info;
302                 info.name = it->getKeyData();
303                 info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
304                 _symbols.push_back(info);
305             }
306         }
307         
308     }
309     
310     return _symbols.size();
311 }
312
313
314 lto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index)
315 {
316     if ( index < _symbols.size() )
317         return _symbols[index].attributes;
318     else
319         return lto_symbol_attributes(0);
320 }
321
322 const char* LTOModule::getSymbolName(uint32_t index)
323 {
324     if ( index < _symbols.size() )
325         return _symbols[index].name;
326     else
327         return NULL;
328 }
329