llvm.org GIT mirror llvm / ef194ed
fixes from review of first commit git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47695 91177308-0d34-0410-b5e6-96231b3b80d8 Nick Kledzik 11 years ago
6 changed file(s) with 195 addition(s) and 213 deletion(s). Raw diff Collapse all Expand all
217217 /**
218218 * Generates code for all added modules into one native object file.
219219 * On sucess returns a pointer to a generated mach-o/ELF buffer and
220 * length set to the buffer size. Client owns the buffer and should
221 * free() it when done.
220 * length set to the buffer size. The buffer is owned by the
221 * lto_code_gen_t and will be freed when lto_codegen_dispose()
222 * is called, or lto_codegen_compile() is called again.
222223 * On failure, returns NULL (check lto_get_error_message() for details).
223224 */
224 extern void*
225 extern const void*
225226 lto_codegen_compile(lto_code_gen_t cg, size_t* length);
226227
227228
1111 //
1212 //===----------------------------------------------------------------------===//
1313
14 #include "LTOModule.h"
15 #include "LTOCodeGenerator.h"
16
17
1418 #include "llvm/Module.h"
1519 #include "llvm/PassManager.h"
1620 #include "llvm/Linker.h"
1822 #include "llvm/DerivedTypes.h"
1923 #include "llvm/ModuleProvider.h"
2024 #include "llvm/Bitcode/ReaderWriter.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/FileUtilities.h"
2325 #include "llvm/Support/SystemUtils.h"
2426 #include "llvm/Support/Mangler.h"
2527 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/System/Program.h"
2728 #include "llvm/System/Signals.h"
2829 #include "llvm/Analysis/Passes.h"
2930 #include "llvm/Analysis/LoopPass.h"
3031 #include "llvm/Analysis/Verifier.h"
32 #include "llvm/Analysis/LoadValueNumbering.h"
3133 #include "llvm/CodeGen/FileWriters.h"
32 #include "llvm/Target/SubtargetFeature.h"
3334 #include "llvm/Target/TargetOptions.h"
3435 #include "llvm/Target/TargetData.h"
3536 #include "llvm/Target/TargetMachine.h"
3738 #include "llvm/Target/TargetAsmInfo.h"
3839 #include "llvm/Transforms/IPO.h"
3940 #include "llvm/Transforms/Scalar.h"
40 #include "llvm/Analysis/LoadValueNumbering.h"
41 #include "llvm/Support/MathExtras.h"
4241 #include "llvm/Config/config.h"
4342
44 #include "LTOModule.h"
45 #include "LTOCodeGenerator.h"
4643
4744 #include
4845 #include
6764 LTOCodeGenerator::LTOCodeGenerator()
6865 : _linker("LinkTimeOptimizer", "ld-temp.o"), _target(NULL),
6966 _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false),
70 _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC)
67 _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC),
68 _nativeObjectFile(NULL)
7169 {
7270
7371 }
7472
7573 LTOCodeGenerator::~LTOCodeGenerator()
7674 {
77 // FIXME
75 delete _target;
76 delete _nativeObjectFile;
7877 }
7978
8079
150149 }
151150
152151
153 void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
154 {
155 // make unqiue temp .s file to put generated assembly code
152 const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
153 {
154 // make unique temp .s file to put generated assembly code
156155 sys::Path uniqueAsmPath("lto-llvm.s");
157156 if ( uniqueAsmPath.createTemporaryFileOnDisk(true, &errMsg) )
158157 return NULL;
168167 return NULL;
169168 }
170169
171 // make unqiue temp .o file to put generated object file
170 // make unique temp .o file to put generated object file
172171 sys::PathWithStatus uniqueObjPath("lto-llvm.o");
173172 if ( uniqueObjPath.createTemporaryFileOnDisk(true, &errMsg) ) {
174173 if ( uniqueAsmPath.exists() )
178177 sys::RemoveFileOnSignal(uniqueObjPath);
179178
180179 // assemble the assembly code
181 void* buffer = NULL;
180 const std::string& uniqueObjStr = uniqueObjPath.toString();
182181 bool asmResult = this->assemble(uniqueAsmPath.toString(),
183 uniqueObjPath.toString(), errMsg);
182 uniqueObjStr, errMsg);
184183 if ( !asmResult ) {
184 // remove old buffer if compile() called twice
185 delete _nativeObjectFile;
186
185187 // read .o file into memory buffer
186 const sys::FileStatus* objStatus;
187 objStatus = uniqueObjPath.getFileStatus(false, &errMsg);
188 if ( objStatus != NULL ) {
189 *length = objStatus->getSize();
190 // use malloc() because caller will own this buffer and free() it
191 buffer = ::malloc(*length);
192 if ( buffer != NULL ) {
193 int fd = ::open(uniqueObjPath.c_str(), O_RDONLY, 0);
194 if ( fd != -1 ) {
195 // read object file contents into buffer
196 if ( ::read(fd, buffer, *length) != (ssize_t)*length ) {
197 errMsg = "error reading object file";
198 free(buffer);
199 buffer = NULL;
200 }
201 close(fd);
202 }
203 else {
204 errMsg = "error opening object file";
205 free(buffer);
206 buffer = NULL;
207 }
208 }
209 else {
210 errMsg = "error mallocing space for object file";
211 }
212 }
213 else {
214 errMsg = "error stat'ing object file";
215 }
216 }
217 // clean up temp files
188 _nativeObjectFile = MemoryBuffer::getFile(&uniqueObjStr[0],
189 uniqueObjStr.size(), &errMsg);
190 }
191
192 // remove temp files
218193 uniqueAsmPath.eraseFromDisk();
219194 uniqueObjPath.eraseFromDisk();
220 return buffer;
195
196 // return buffer, unless error
197 if ( _nativeObjectFile == NULL )
198 return NULL;
199 *length = _nativeObjectFile->getBufferSize();
200 return _nativeObjectFile->getBufferStart();
221201 }
222202
223203
1717 #include "llvm/Linker.h"
1818 #include "llvm/ADT/StringMap.h"
1919
20 #include
2021
2122
2223 //
3334 bool setDebugInfo(lto_debug_model, std::string& errMsg);
3435 bool setCodePICModel(lto_codegen_model, std::string& errMsg);
3536 void addMustPreserveSymbol(const char* sym);
36 bool writeMergedModules(const char* path, std::string& errMsg);
37 void* compile(size_t* length, std::string& errMsg);
37 bool writeMergedModules(const char* path,
38 std::string& errMsg);
39 const void* compile(size_t* length, std::string& errMsg);
3840
3941 private:
4042 bool generateAssemblyCode(std::ostream& out,
5254 bool _scopeRestrictionsDone;
5355 lto_codegen_model _codeModel;
5456 StringSet _mustPreserveSymbols;
57 llvm::MemoryBuffer* _nativeObjectFile;
5558 };
5659
5760 #endif // LTO_CODE_GENERATOR_H
1111 //
1212 //===----------------------------------------------------------------------===//
1313
14 #include "LTOModule.h"
15
1416 #include "llvm/Module.h"
15 #include "llvm/PassManager.h"
16 #include "llvm/Linker.h"
17 #include "llvm/Constants.h"
18 #include "llvm/DerivedTypes.h"
1917 #include "llvm/ModuleProvider.h"
18 #include "llvm/ADT/OwningPtr.h"
2019 #include "llvm/Bitcode/ReaderWriter.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/FileUtilities.h"
2320 #include "llvm/Support/SystemUtils.h"
2421 #include "llvm/Support/Mangler.h"
2522 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/System/Program.h"
23 #include "llvm/Support/MathExtras.h"
2724 #include "llvm/System/Path.h"
28 #include "llvm/System/Signals.h"
29 #include "llvm/Target/SubtargetFeature.h"
30 #include "llvm/Target/TargetOptions.h"
31 #include "llvm/Target/TargetData.h"
3225 #include "llvm/Target/TargetMachine.h"
3326 #include "llvm/Target/TargetMachineRegistry.h"
3427 #include "llvm/Target/TargetAsmInfo.h"
35 #include "llvm/Transforms/IPO.h"
36 #include "llvm/Transforms/Scalar.h"
37 #include "llvm/Analysis/LoadValueNumbering.h"
38 #include "llvm/Support/MathExtras.h"
39
40 #include "LTOModule.h"
28
4129
4230 #include
4331
5745 bool LTOModule::isBitcodeFileForTarget(const void* mem,
5846 size_t length, const char* triplePrefix)
5947 {
60 bool result = false;
61 MemoryBuffer* buffer;
62 buffer = MemoryBuffer::getMemBuffer((char*)mem, (char*)mem+length);
63 if ( buffer != NULL ) {
64 ModuleProvider* mp = getBitcodeModuleProvider(buffer);
65 if ( mp != NULL ) {
66 std::string actualTarget = mp->getModule()->getTargetTriple();
67 if ( strncmp(actualTarget.c_str(), triplePrefix,
68 strlen(triplePrefix)) == 0) {
69 result = true;
70 }
71 // mp destructor will delete buffer
72 delete mp;
73 }
74 else {
75 // if getBitcodeModuleProvider failed, we need to delete buffer
76 delete buffer;
77 }
78 }
79 return result;
80 }
48 MemoryBuffer* buffer = MemoryBuffer::getMemBuffer((char*)mem,
49 (char*)mem+length);
50 if ( buffer == NULL )
51 return false;
52 return isTargetMatch(buffer, triplePrefix);
53 }
54
8155
8256 bool LTOModule::isBitcodeFileForTarget(const char* path,
8357 const char* triplePrefix)
8458 {
85 bool result = false;
86 MemoryBuffer* buffer;
87 buffer = MemoryBuffer::getFile(path, strlen(path));
88 if ( buffer != NULL ) {
89 ModuleProvider* mp = getBitcodeModuleProvider(buffer);
90 if ( mp != NULL ) {
91 std::string actualTarget = mp->getModule()->getTargetTriple();
92 if ( strncmp(actualTarget.c_str(), triplePrefix,
93 strlen(triplePrefix)) == 0) {
94 result = true;
95 }
96 // mp destructor will delete buffer
97 delete mp;
98 }
99 else {
100 // if getBitcodeModuleProvider failed, we need to delete buffer
101 delete buffer;
102 }
103 }
104 return result;
59 MemoryBuffer* buffer = MemoryBuffer::getFile(path, strlen(path));
60 if ( buffer == NULL )
61 return false;
62 return isTargetMatch(buffer, triplePrefix);
63 }
64
65 // takes ownership of buffer
66 bool LTOModule::isTargetMatch(MemoryBuffer* buffer, const char* triplePrefix)
67 {
68 OwningPtr mp(getBitcodeModuleProvider(buffer));
69 // on success, mp owns buffer and both are deleted at end of this method
70 if ( !mp ) {
71 delete buffer;
72 return false;
73 }
74 std::string actualTarget = mp->getModule()->getTargetTriple();
75 return ( strncmp(actualTarget.c_str(), triplePrefix,
76 strlen(triplePrefix)) == 0);
10577 }
10678
10779
11082 {
11183 }
11284
113 LTOModule::~LTOModule()
114 {
115 delete _module;
116 if ( _target != NULL )
117 delete _target;
118 }
119
120
12185 LTOModule* LTOModule::makeLTOModule(const char* path, std::string& errMsg)
12286 {
123 MemoryBuffer* buffer = MemoryBuffer::getFile(path, strlen(path));
124 if ( buffer != NULL ) {
125 Module* m = ParseBitcodeFile(buffer, &errMsg);
126 delete buffer;
127 if ( m != NULL ) {
128 const TargetMachineRegistry::entry* march =
129 TargetMachineRegistry::getClosestStaticTargetForModule(*m, errMsg);
130 if ( march != NULL ) {
131 std::string features;
132 TargetMachine* target = march->CtorFn(*m, features);
133 return new LTOModule(m, target);
134 }
135 }
136 }
137 return NULL;
87 OwningPtr buffer(MemoryBuffer::getFile(
88 path, strlen(path), &errMsg));
89 if ( !buffer )
90 return NULL;
91 return makeLTOModule(buffer.get(), errMsg);
13892 }
13993
14094 LTOModule* LTOModule::makeLTOModule(const void* mem, size_t length,
14195 std::string& errMsg)
14296 {
143 MemoryBuffer* buffer;
144 buffer = MemoryBuffer::getMemBuffer((char*)mem, (char*)mem+length);
145 if ( buffer != NULL ) {
146 Module* m = ParseBitcodeFile(buffer, &errMsg);
147 delete buffer;
148 if ( m != NULL ) {
149 const TargetMachineRegistry::entry* march =
150 TargetMachineRegistry::getClosestStaticTargetForModule(*m, errMsg);
151 if ( march != NULL ) {
152 std::string features;
153 TargetMachine* target = march->CtorFn(*m, features);
154 return new LTOModule(m, target);
97 OwningPtr 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 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);
155138 }
156139 }
157140 }
158 return NULL;
159 }
160
161
162 const char* LTOModule::getTargetTriple()
163 {
164 return _module->getTargetTriple().c_str();
165 }
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
166155
167156 void LTOModule::addDefinedSymbol(GlobalValue* def, Mangler &mangler,
168157 bool isFunction)
169158 {
159 // string is owned by _defines
170160 const char* symbolName = ::strdup(mangler.getValueName(def).c_str());
171161
172162 // set alignment part log2() can have rounding errors
173163 uint32_t align = def->getAlignment();
174 uint32_t attr = align ? __builtin_ctz(def->getAlignment()) : 0;
164 uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0;
175165
176166 // set permissions part
177167 if ( isFunction )
219209 }
220210
221211
222 void LTOModule::addUndefinedSymbol(const char* name)
223 {
212 void LTOModule::addPotentialUndefinedSymbol(GlobalValue* decl, Mangler &mangler)
213 {
214 const char* name = mangler.getValueName(decl).c_str();
224215 // ignore all llvm.* symbols
225216 if ( strncmp(name, "llvm.", 5) != 0 ) {
226217 _undefines[name] = 1;
234225
235226 if (GlobalValue* gv = dyn_cast(value)) {
236227 if ( !gv->hasExternalLinkage() )
237 addUndefinedSymbol(mangler.getValueName(gv).c_str());
228 addPotentialUndefinedSymbol(gv, mangler);
238229 }
239230
240231 // GlobalValue, even with InternalLinkage type, may have operands with
246237 }
247238 }
248239
249
250 uint32_t LTOModule::getSymbolCount()
240 void LTOModule::lazyParseSymbols()
251241 {
252242 if ( !_symbolsParsed ) {
253243 _symbolsParsed = true;
257247
258248 // add functions
259249 for (Module::iterator f = _module->begin(); f != _module->end(); ++f) {
260 if ( f->isDeclaration() ) {
261 addUndefinedSymbol(mangler.getValueName(f).c_str());
262 }
263 else {
264 addDefinedSymbol(f, mangler, true);
265 // add external symbols referenced by this function.
266 for (Function::iterator b = f->begin(); b != f->end(); ++b) {
267 for (BasicBlock::iterator i = b->begin();
268 i != b->end(); ++i) {
269 for (unsigned count = 0, total = i->getNumOperands();
270 count != total; ++count) {
271 findExternalRefs(i->getOperand(count), mangler);
272 }
273 }
274 }
275 }
250 if ( f->isDeclaration() )
251 addPotentialUndefinedSymbol(f, mangler);
252 else
253 addDefinedFunctionSymbol(f, mangler);
276254 }
277255
278256 // add data
279257 for (Module::global_iterator v = _module->global_begin(),
280258 e = _module->global_end(); v != e; ++v) {
281 if ( v->isDeclaration() ) {
282 addUndefinedSymbol(mangler.getValueName(v).c_str());
283 }
284 else {
285 addDefinedSymbol(v, mangler, false);
286 // add external symbols referenced by this data
287 for (unsigned count = 0, total = v->getNumOperands();
288 count != total; ++count) {
289 findExternalRefs(v->getOperand(count), mangler);
290 }
291 }
259 if ( v->isDeclaration() )
260 addPotentialUndefinedSymbol(v, mangler);
261 else
262 addDefinedDataSymbol(v, mangler);
292263 }
293264
294265 // make symbols for all undefines
296267 it != _undefines.end(); ++it) {
297268 // if this symbol also has a definition, then don't make an undefine
298269 // because it is a tentative definition
299 if ( _defines.find(it->getKeyData(), it->getKeyData()+it->getKeyLength()) == _defines.end() ) {
270 if ( _defines.count(it->getKeyData(), it->getKeyData()+
271 it->getKeyLength()) == 0 ) {
300272 NameAndAttributes info;
301273 info.name = it->getKeyData();
302274 info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
303275 _symbols.push_back(info);
304276 }
305277 }
306
307 }
308
278 }
279 }
280
281
282 uint32_t LTOModule::getSymbolCount()
283 {
284 lazyParseSymbols();
309285 return _symbols.size();
310286 }
311287
312288
313289 lto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index)
314290 {
291 lazyParseSymbols();
315292 if ( index < _symbols.size() )
316293 return _symbols[index].attributes;
317294 else
320297
321298 const char* LTOModule::getSymbolName(uint32_t index)
322299 {
300 lazyParseSymbols();
323301 if ( index < _symbols.size() )
324302 return _symbols[index].name;
325303 else
1414 #define LTO_MODULE_H
1515
1616 #include "llvm/Module.h"
17 #include "llvm/GlobalValue.h"
18 #include "llvm/Constants.h"
19 #include "llvm/Support/Mangler.h"
17 #include "llvm/ADT/OwningPtr.h"
2018 #include "llvm/Target/TargetMachine.h"
2119 #include "llvm/ADT/StringMap.h"
2220
2321 #include "llvm-c/lto.h"
2422
2523 #include
24 #include
25
26
27 // forward references to llvm classes
28 namespace llvm {
29 class Mangler;
30 class MemoryBuffer;
31 class GlobalValue;
32 class Value;
33 class Function;
34 }
2635
2736
2837 //
4352 static LTOModule* makeLTOModule(const char* path, std::string& errMsg);
4453 static LTOModule* makeLTOModule(const void* mem, size_t length,
4554 std::string& errMsg);
46 ~LTOModule();
4755
4856 const char* getTargetTriple();
4957 uint32_t getSymbolCount();
5058 lto_symbol_attributes getSymbolAttributes(uint32_t index);
5159 const char* getSymbolName(uint32_t index);
5260
53 llvm::Module * getLLVVMModule() { return _module; }
54 bool targetSupported() { return (_target != NULL); }
61 llvm::Module * getLLVVMModule() { return _module.get(); }
5562
5663 private:
5764 LTOModule(llvm::Module* m, llvm::TargetMachine* t);
5865
66 void lazyParseSymbols();
5967 void addDefinedSymbol(llvm::GlobalValue* def,
6068 llvm::Mangler& mangler,
6169 bool isFunction);
62 void addUndefinedSymbol(const char* name);
70 void addPotentialUndefinedSymbol(llvm::GlobalValue* decl,
71 llvm::Mangler &mangler);
6372 void findExternalRefs(llvm::Value* value,
6473 llvm::Mangler& mangler);
74 void addDefinedFunctionSymbol(llvm::Function* f,
75 llvm::Mangler &mangler);
76 void addDefinedDataSymbol(llvm::GlobalValue* v,
77 llvm::Mangler &mangler);
78 static bool isTargetMatch(llvm::MemoryBuffer* memBuffer,
79 const char* triplePrefix);
6580
81 static LTOModule* makeLTOModule(llvm::MemoryBuffer* buffer,
82 std::string& errMsg);
83
6684 typedef llvm::StringMap StringSet;
6785
6886 struct NameAndAttributes {
7088 lto_symbol_attributes attributes;
7189 };
7290
73 llvm::Module * _module;
74 llvm::TargetMachine * _target;
75 bool _symbolsParsed;
76 std::vector _symbols;
77 StringSet _defines; // only needed to disambiguate tentative definitions
78 StringSet _undefines; // only needed to disambiguate tentative definitions
91 llvm::OwningPtr _module;
92 llvm::OwningPtr _target;
93 bool _symbolsParsed;
94 std::vector _symbols;
95 // _defines and _undefines only needed to disambiguate tentative definitions
96 StringSet _defines;
97 StringSet _undefines;
7998 };
8099
81100 #endif // LTO_MODULE_H
3232 }
3333
3434 //
35 // returns the last error string or NULL if last operation was sucessful
35 // returns the last error string or NULL if last operation was successful
3636 //
3737 const char* lto_get_error_message()
3838 {
223223
224224
225225 //
226 // generates code for all added modules into one object file
227 // On sucess returns a pointer to a generated mach-o buffer and
228 // length set to the buffer size. Client must free() the buffer
229 // when done.
230 // On failure, returns NULL (check lto_get_error_message() for details)
231 //
232 extern void*
226 // Generates code for all added modules into one native object file.
227 // On sucess returns a pointer to a generated mach-o/ELF buffer and
228 // length set to the buffer size. The buffer is owned by the
229 // lto_code_gen_t and will be freed when lto_codegen_dispose()
230 // is called, or lto_codegen_compile() is called again.
231 // On failure, returns NULL (check lto_get_error_message() for details).
232 //
233 extern const void*
233234 lto_codegen_compile(lto_code_gen_t cg, size_t* length)
234235 {
235236 return cg->compile(length, sLastErrorString);