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