Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/gen/runtime.cpp

Revision 1633:5c0cebff9be8, 36.4 kB (checked in by Christian Kamm <kamm incasoftware de>, 2 years ago)

Improve array append performance.

Actually use the appropriate runtime function, instead of just
growing the array by one!

Line 
1 #include "gen/llvm.h"
2 #include "llvm/Module.h"
3 #include "llvm/Attributes.h"
4 #include "llvm/Bitcode/ReaderWriter.h"
5 #include "llvm/Support/MemoryBuffer.h"
6 #include "llvm/Support/CommandLine.h"
7
8 #include "root.h"
9 #include "mars.h"
10 #include "lexer.h"
11 #include "dsymbol.h"
12 #include "mtype.h"
13 #include "aggregate.h"
14
15 #include "gen/runtime.h"
16 #include "gen/logger.h"
17 #include "gen/tollvm.h"
18 #include "gen/irstate.h"
19
20 using namespace llvm::Attribute;
21
22 //////////////////////////////////////////////////////////////////////////////////////////////////
23
24 static llvm::cl::opt<bool> noruntime("noruntime",
25     llvm::cl::desc("Do not allow code that generates implicit runtime calls"),
26     llvm::cl::ZeroOrMore);
27
28 //////////////////////////////////////////////////////////////////////////////////////////////////
29
30 static llvm::Module* M = NULL;
31 static bool runtime_failed = false;
32
33 static void LLVM_D_BuildRuntimeModule();
34
35 //////////////////////////////////////////////////////////////////////////////////////////////////
36
37 bool LLVM_D_InitRuntime()
38 {
39     Logger::println("*** Initializing D runtime declarations ***");
40     LOG_SCOPE;
41
42     if (!M)
43         LLVM_D_BuildRuntimeModule();
44
45     return true;
46 }
47
48 void LLVM_D_FreeRuntime()
49 {
50     if (M) {
51         Logger::println("*** Freeing D runtime declarations ***");
52         delete M;
53         M = NULL;
54     }
55 }
56
57 //////////////////////////////////////////////////////////////////////////////////////////////////
58
59 llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name)
60 {
61     if (noruntime) {
62         error("No implicit runtime calls allowed with -noruntime option enabled");
63         fatal();
64     }
65
66     if (!M) {
67         assert(!runtime_failed);
68         LLVM_D_InitRuntime();
69     }
70
71     llvm::Function* fn = target->getFunction(name);
72     if (fn)
73         return fn;
74
75     fn = M->getFunction(name);
76     if (!fn) {
77         printf("Runtime function '%s' was not found\n", name);
78         assert(0);
79         //return NULL;
80     }
81
82     const llvm::FunctionType* fnty = fn->getFunctionType();
83     llvm::Function* resfn = llvm::cast<llvm::Function>(target->getOrInsertFunction(name, fnty));
84     resfn->setAttributes(fn->getAttributes());
85     return resfn;
86 }
87
88 //////////////////////////////////////////////////////////////////////////////////////////////////
89
90 llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* name)
91 {
92     llvm::GlobalVariable* gv = target->getNamedGlobal(name);
93     if (gv) {
94         return gv;
95     }
96
97     if (noruntime) {
98         error("No implicit runtime calls allowed with -noruntime option enabled");
99         fatal();
100     }
101
102     if (!M) {
103         assert(!runtime_failed);
104         LLVM_D_InitRuntime();
105     }
106
107     llvm::GlobalVariable* g = M->getNamedGlobal(name);
108     if (!g) {
109         error("Runtime global '%s' was not found", name);
110         fatal();
111         //return NULL;
112     }
113
114     const llvm::PointerType* t = g->getType();
115     return new llvm::GlobalVariable(*target, t->getElementType(),g->isConstant(),g->getLinkage(),NULL,g->getName());
116 }
117
118 //////////////////////////////////////////////////////////////////////////////////////////////////
119
120 static const LLType* rt_ptr(const LLType* t)
121 {
122     return getPtrToType(t);
123 }
124
125 static const LLType* rt_array(const LLType* elemty)
126 {
127     return llvm::StructType::get(gIR->context(), DtoSize_t(), rt_ptr(elemty), NULL);
128 }
129
130 static const LLType* rt_dg1()
131 {
132     std::vector<const LLType*> types;
133     types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
134     types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
135     const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::getInt32Ty(gIR->context()), types, false);
136     return llvm::StructType::get(gIR->context(), rt_ptr(LLType::getInt8Ty(gIR->context())), rt_ptr(fty), NULL);
137 }
138
139 static const LLType* rt_dg2()
140 {
141     std::vector<const LLType*> types;
142     types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
143     types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
144     types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context())));
145     const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::getInt32Ty(gIR->context()), types, false);
146     return llvm::StructType::get(gIR->context(), rt_ptr(LLType::getInt8Ty(gIR->context())), rt_ptr(fty), NULL);
147 }
148
149 static void LLVM_D_BuildRuntimeModule()
150 {
151     Logger::println("building module");
152     M = new llvm::Module("ldc internal runtime", gIR->context());
153
154     Logger::println("building basic types");
155     const LLType* voidTy = LLType::getVoidTy(gIR->context());
156     const LLType* boolTy = LLType::getInt1Ty(gIR->context());
157     const LLType* byteTy = LLType::getInt8Ty(gIR->context());
158     const LLType* shortTy = LLType::getInt16Ty(gIR->context());
159     const LLType* intTy = LLType::getInt32Ty(gIR->context());
160     const LLType* longTy = LLType::getInt64Ty(gIR->context());
161     const LLType* sizeTy = DtoSize_t();
162
163     Logger::println("building float types");
164     const LLType* floatTy = LLType::getFloatTy(gIR->context());
165     const LLType* doubleTy = LLType::getDoubleTy(gIR->context());
166     const LLType* realTy;
167     if ((global.params.cpu == ARCHx86) || (global.params.cpu == ARCHx86_64))
168         realTy = LLType::getX86_FP80Ty(gIR->context());
169     else
170         realTy = LLType::getDoubleTy(gIR->context());
171
172     const LLType* cfloatTy = llvm::StructType::get(gIR->context(), floatTy, floatTy, NULL);
173     const LLType* cdoubleTy = llvm::StructType::get(gIR->context(), doubleTy, doubleTy, NULL);
174     const LLType* crealTy = llvm::StructType::get(gIR->context(), realTy, realTy, NULL);
175
176     Logger::println("building aggr types");
177     const LLType* voidPtrTy = rt_ptr(byteTy);
178     const LLType* stringTy = rt_array(byteTy);
179     const LLType* wstringTy = rt_array(shortTy);
180     const LLType* dstringTy = rt_array(intTy);
181
182     Logger::println("building class types");
183     const LLType* objectTy = DtoType(ClassDeclaration::object->type);
184     const LLType* classInfoTy = DtoType(ClassDeclaration::classinfo->type);
185     const LLType* typeInfoTy = DtoType(Type::typeinfo->type);
186
187     Logger::println("building aa type");
188     const LLType* aaTy = rt_ptr(llvm::OpaqueType::get(gIR->context()));
189
190     Logger::println("building functions");
191
192     /////////////////////////////////////////////////////////////////////////////////////
193     /////////////////////////////////////////////////////////////////////////////////////
194     /////////////////////////////////////////////////////////////////////////////////////
195
196     // Construct some attribute lists used below (possibly multiple times)
197     llvm::AttrListPtr
198         NoAttrs,
199         Attr_NoAlias
200             = NoAttrs.addAttr(0, NoAlias),
201         Attr_NoUnwind
202             = NoAttrs.addAttr(~0U, NoUnwind),
203         Attr_ReadOnly
204             = NoAttrs.addAttr(~0U, ReadOnly),
205         Attr_ReadOnly_NoUnwind
206             = Attr_ReadOnly.addAttr(~0U, NoUnwind),
207         Attr_ReadOnly_1_NoCapture
208             = Attr_ReadOnly.addAttr(1, NoCapture),
209         Attr_ReadOnly_1_3_NoCapture
210             = Attr_ReadOnly_1_NoCapture.addAttr(3, NoCapture),
211         Attr_ReadOnly_1_4_NoCapture
212             = Attr_ReadOnly_1_NoCapture.addAttr(4, NoCapture),
213         Attr_ReadOnly_NoUnwind_1_NoCapture
214             = Attr_ReadOnly_1_NoCapture.addAttr(~0U, NoUnwind),
215         Attr_ReadNone
216             = NoAttrs.addAttr(~0U, ReadNone),
217         Attr_1_NoCapture
218             = NoAttrs.addAttr(1, NoCapture),
219         Attr_NoAlias_1_NoCapture
220             = Attr_1_NoCapture.addAttr(0, NoAlias),
221         Attr_NoAlias_3_NoCapture
222             = Attr_NoAlias.addAttr(3, NoCapture),
223         Attr_1_2_NoCapture
224             = Attr_1_NoCapture.addAttr(2, NoCapture),
225         Attr_1_3_NoCapture
226             = Attr_1_NoCapture.addAttr(3, NoCapture),
227         Attr_1_4_NoCapture
228             = Attr_1_NoCapture.addAttr(4, NoCapture);
229
230     /////////////////////////////////////////////////////////////////////////////////////
231     /////////////////////////////////////////////////////////////////////////////////////
232     /////////////////////////////////////////////////////////////////////////////////////
233
234     // void _d_assert( char[] file, uint line )
235     // void _d_array_bounds( char[] file, uint line )
236     // void _d_switch_error( char[] file, uint line )
237     {
238         llvm::StringRef fname("_d_assert");
239         llvm::StringRef fname2("_d_array_bounds");
240         llvm::StringRef fname3("_d_switch_error");
241         std::vector<const LLType*> types;
242         types.push_back(stringTy);
243         types.push_back(intTy);
244         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
245         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
246         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
247         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M);
248     }
249
250     // void _d_assert_msg( char[] msg, char[] file, uint line )
251     {
252         llvm::StringRef fname("_d_assert_msg");
253         std::vector<const LLType*> types;
254         types.push_back(stringTy);
255         types.push_back(stringTy);
256         types.push_back(intTy);
257         const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
258         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
259     }
260
261     /////////////////////////////////////////////////////////////////////////////////////
262     /////////////////////////////////////////////////////////////////////////////////////
263     /////////////////////////////////////////////////////////////////////////////////////
264
265     // void* _d_allocmemoryT(TypeInfo ti)
266     {
267         llvm::StringRef fname("_d_allocmemoryT");
268         std::vector<const LLType*> types;
269         types.push_back(typeInfoTy);
270         const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
271         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
272             ->setAttributes(Attr_NoAlias);
273     }
274
275     // void* _d_newarrayT(TypeInfo ti, size_t length)
276     // void* _d_newarrayiT(TypeInfo ti, size_t length)
277     // void* _d_newarrayvT(TypeInfo ti, size_t length)
278     {
279         llvm::StringRef fname("_d_newarrayT");
280         llvm::StringRef fname2("_d_newarrayiT");
281         llvm::StringRef fname3("_d_newarrayvT");
282         std::vector<const LLType*> types;
283         types.push_back(typeInfoTy);
284         types.push_back(sizeTy);
285         const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
286         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
287             ->setAttributes(Attr_NoAlias);
288         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)
289             ->setAttributes(Attr_NoAlias);
290         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M)
291             ->setAttributes(Attr_NoAlias);
292     }
293
294     // void* _d_newarraymT(TypeInfo ti, size_t length, size_t* dims)
295     // void* _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims)
296     // void* _d_newarraymvT(TypeInfo ti, size_t length, size_t* dims)
297     {
298         llvm::StringRef fname("_d_newarraymT");
299         llvm::StringRef fname2("_d_newarraymiT");
300         llvm::StringRef fname3("_d_newarraymvT");
301         std::vector<const LLType*> types;
302         types.push_back(typeInfoTy);
303         types.push_back(sizeTy);
304         types.push_back(rt_ptr(sizeTy));
305         const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
306         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
307             ->setAttributes(Attr_NoAlias_3_NoCapture);
308         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)
309             ->setAttributes(Attr_NoAlias_3_NoCapture);
310         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M)
311             ->setAttributes(Attr_NoAlias_3_NoCapture);
312     }
313
314     // void* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
315     // void* _d_arraysetlengthiT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
316     {
317         llvm::StringRef fname("_d_arraysetlengthT");
318         llvm::StringRef fname2("_d_arraysetlengthiT");
319         std::vector<const LLType*> types;
320         types.push_back(typeInfoTy);
321         types.push_back(sizeTy);
322         types.push_back(sizeTy);
323         types.push_back(voidPtrTy);
324         const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
325         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
326         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
327     }
328
329     // void* _d_arrayappendcT(TypeInfo ti, void* array, void* element)
330     {
331         llvm::StringRef fname("_d_arrayappendcT");
332         std::vector<const LLType*> types;
333         types.push_back(typeInfoTy);
334         types.push_back(voidPtrTy);
335         types.push_back(voidPtrTy);
336         const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
337         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
338     }
339
340     // Object _d_allocclass(ClassInfo ci)
341     {
342         llvm::StringRef fname("_d_allocclass");
343         std::vector<const LLType*> types;
344         types.push_back(classInfoTy);
345         const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
346         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
347             ->setAttributes(Attr_NoAlias);
348     }
349
350     // void _d_delarray(size_t plength, void* pdata)
351     {
352         llvm::StringRef fname("_d_delarray");
353         std::vector<const LLType*> types;
354         types.push_back(sizeTy);
355         types.push_back(voidPtrTy);
356         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
357         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
358     }
359
360     // void _d_delmemory(void* p)
361     // void _d_delinterface(void* p)
362     // void _d_callfinalizer(void* p)
363     {
364         llvm::StringRef fname("_d_delmemory");
365         llvm::StringRef fname2("_d_delinterface");
366         llvm::StringRef fname3("_d_callfinalizer");
367         std::vector<const LLType*> types;
368         types.push_back(voidPtrTy);
369         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
370         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
371         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
372         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M);
373     }
374
375     // void _d_delclass(Object p)
376     {
377         llvm::StringRef fname("_d_delclass");
378         std::vector<const LLType*> types;
379         types.push_back(objectTy);
380         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
381         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
382     }
383
384     /////////////////////////////////////////////////////////////////////////////////////
385     /////////////////////////////////////////////////////////////////////////////////////
386     /////////////////////////////////////////////////////////////////////////////////////
387
388     #define ARRAY_INIT(TY,suffix) \
389     { \
390         std::string fname = (llvm::StringRef("_d_array_init_") + llvm::StringRef(suffix)).str(); \
391         std::vector<const LLType*> types; \
392         types.push_back(rt_ptr(TY)); \
393         types.push_back(sizeTy); \
394         types.push_back(TY); \
395         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); \
396         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) \
397             ->setAttributes(Attr_1_NoCapture); \
398     }
399
400     ARRAY_INIT(shortTy,"i16")
401     ARRAY_INIT(intTy,"i32")
402     ARRAY_INIT(longTy,"i64")
403     ARRAY_INIT(floatTy,"float")
404     ARRAY_INIT(doubleTy,"double")
405     ARRAY_INIT(realTy,"real")
406     ARRAY_INIT(cfloatTy,"cfloat")
407     ARRAY_INIT(cdoubleTy,"cdouble")
408     ARRAY_INIT(crealTy,"creal")
409     ARRAY_INIT(voidPtrTy,"pointer")
410
411     #undef ARRAY_INIT
412
413     // array init mem
414     // void _d_array_init_mem(void* a, size_t na, void* v, size_t nv)
415     // +
416     // array slice copy when assertions are on!
417     // void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen)
418     {
419         llvm::StringRef fname("_d_array_init_mem");
420         llvm::StringRef fname2("_d_array_slice_copy");
421         std::vector<const LLType*> types;
422         types.push_back(voidPtrTy);
423         types.push_back(sizeTy);
424         types.push_back(voidPtrTy);
425         types.push_back(sizeTy);
426         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
427         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
428             ->setAttributes(Attr_1_3_NoCapture);
429         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)
430             ->setAttributes(Attr_1_3_NoCapture);
431     }
432
433     /////////////////////////////////////////////////////////////////////////////////////
434     /////////////////////////////////////////////////////////////////////////////////////
435     /////////////////////////////////////////////////////////////////////////////////////
436
437     // int _aApplycd1(char[] aa, dg_t dg)
438     #define STR_APPLY1(TY,a,b) \
439     { \
440         llvm::StringRef fname(a); \
441         llvm::StringRef fname2(b); \
442         std::vector<const LLType*> types; \
443         types.push_back(TY); \
444         types.push_back(rt_dg1()); \
445         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
446         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
447         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
448     }
449     STR_APPLY1(stringTy, "_aApplycw1", "_aApplycd1")
450     STR_APPLY1(wstringTy, "_aApplywc1", "_aApplywd1")
451     STR_APPLY1(dstringTy, "_aApplydc1", "_aApplydw1")
452     #undef STR_APPLY
453
454     // int _aApplycd2(char[] aa, dg2_t dg)
455     #define STR_APPLY2(TY,a,b) \
456     { \
457         llvm::StringRef fname(a); \
458         llvm::StringRef fname2(b); \
459         std::vector<const LLType*> types; \
460         types.push_back(TY); \
461         types.push_back(rt_dg2()); \
462         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
463         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
464         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
465     }
466     STR_APPLY2(stringTy, "_aApplycw2", "_aApplycd2")
467     STR_APPLY2(wstringTy, "_aApplywc2", "_aApplywd2")
468     STR_APPLY2(dstringTy, "_aApplydc2", "_aApplydw2")
469     #undef STR_APPLY2
470
471     #define STR_APPLY_R1(TY,a,b) \
472     { \
473         llvm::StringRef fname(a); \
474         llvm::StringRef fname2(b); \
475         std::vector<const LLType*> types; \
476         types.push_back(TY); \
477         types.push_back(rt_dg1()); \
478         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
479         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
480         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
481     }
482     STR_APPLY_R1(stringTy, "_aApplyRcw1", "_aApplyRcd1")
483     STR_APPLY_R1(wstringTy, "_aApplyRwc1", "_aApplyRwd1")
484     STR_APPLY_R1(dstringTy, "_aApplyRdc1", "_aApplyRdw1")
485     #undef STR_APPLY
486
487     #define STR_APPLY_R2(TY,a,b) \
488     { \
489         llvm::StringRef fname(a); \
490         llvm::StringRef fname2(b); \
491         std::vector<const LLType*> types; \
492         types.push_back(TY); \
493         types.push_back(rt_dg2()); \
494         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
495         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
496         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
497     }
498     STR_APPLY_R2(stringTy, "_aApplyRcw2", "_aApplyRcd2")
499     STR_APPLY_R2(wstringTy, "_aApplyRwc2", "_aApplyRwd2")
500     STR_APPLY_R2(dstringTy, "_aApplyRdc2", "_aApplyRdw2")
501     #undef STR_APPLY2
502
503     /////////////////////////////////////////////////////////////////////////////////////
504     /////////////////////////////////////////////////////////////////////////////////////
505     /////////////////////////////////////////////////////////////////////////////////////
506
507     // fixes the length for dynamic array casts
508     // size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
509     {
510         llvm::StringRef fname("_d_array_cast_len");
511         std::vector<const LLType*> types;
512         types.push_back(sizeTy);
513         types.push_back(sizeTy);
514         types.push_back(sizeTy);
515         const llvm::FunctionType* fty = llvm::FunctionType::get(sizeTy, types, false);
516         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
517             ->setAttributes(Attr_ReadNone);
518     }
519
520     /////////////////////////////////////////////////////////////////////////////////////
521     /////////////////////////////////////////////////////////////////////////////////////
522     /////////////////////////////////////////////////////////////////////////////////////
523
524     // cast to object
525     // Object _d_toObject(void* p)
526     {
527         llvm::StringRef fname("_d_toObject");
528         std::vector<const LLType*> types;
529         types.push_back(voidPtrTy);
530         const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
531         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
532             ->setAttributes(Attr_ReadOnly_NoUnwind);
533     }
534
535     // cast interface
536     // Object _d_interface_cast(void* p, ClassInfo c)
537     {
538         llvm::StringRef fname("_d_interface_cast");
539         std::vector<const LLType*> types;
540         types.push_back(voidPtrTy);
541         types.push_back(classInfoTy);
542         const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
543         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
544             ->setAttributes(Attr_ReadOnly_NoUnwind);
545     }
546
547     // dynamic cast
548     // Object _d_dynamic_cast(Object o, ClassInfo c)
549     {
550         llvm::StringRef fname("_d_dynamic_cast");
551         std::vector<const LLType*> types;
552         types.push_back(objectTy);
553         types.push_back(classInfoTy);
554         const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
555         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
556             ->setAttributes(Attr_ReadOnly_NoUnwind);
557     }
558
559     /////////////////////////////////////////////////////////////////////////////////////
560     /////////////////////////////////////////////////////////////////////////////////////
561     /////////////////////////////////////////////////////////////////////////////////////
562
563     // char[] _adReverseChar(char[] a)
564     // char[] _adSortChar(char[] a)
565     {
566         llvm::StringRef fname("_adReverseChar");
567         llvm::StringRef fname2("_adSortChar");
568         std::vector<const LLType*> types;
569         types.push_back(stringTy);
570         const llvm::FunctionType* fty = llvm::FunctionType::get(stringTy, types, false);
571         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
572         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
573     }
574
575     // wchar[] _adReverseWchar(wchar[] a)
576     // wchar[] _adSortWchar(wchar[] a)
577     {
578         llvm::StringRef fname("_adReverseWchar");
579         llvm::StringRef fname2("_adSortWchar");
580         std::vector<const LLType*> types;
581         types.push_back(wstringTy);
582         const llvm::FunctionType* fty = llvm::FunctionType::get(wstringTy, types, false);
583         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
584         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
585     }
586
587     // void[] _adReverse(void[] a, size_t szelem)
588     {
589         llvm::StringRef fname("_adReverse");
590         std::vector<const LLType*> types;
591         types.push_back(rt_array(byteTy));
592         types.push_back(sizeTy);
593         const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
594         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
595             ->setAttributes(Attr_NoUnwind);
596     }
597
598     // void[] _adDupT(TypeInfo ti, void[] a)
599     {
600         llvm::StringRef fname("_adDupT");
601         std::vector<const LLType*> types;
602         types.push_back(typeInfoTy);
603         types.push_back(rt_array(byteTy));
604         const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
605         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
606     }
607
608     // int _adEq(void[] a1, void[] a2, TypeInfo ti)
609     // int _adCmp(void[] a1, void[] a2, TypeInfo ti)
610     {
611         llvm::StringRef fname("_adEq");
612         llvm::StringRef fname2("_adCmp");
613         std::vector<const LLType*> types;
614         types.push_back(rt_array(byteTy));
615         types.push_back(rt_array(byteTy));
616         types.push_back(typeInfoTy);
617         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
618         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
619             ->setAttributes(Attr_ReadOnly);
620         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)
621             ->setAttributes(Attr_ReadOnly);
622     }
623
624     // int _adCmpChar(void[] a1, void[] a2)
625     {
626         llvm::StringRef fname("_adCmpChar");
627         std::vector<const LLType*> types;
628         types.push_back(rt_array(byteTy));
629         types.push_back(rt_array(byteTy));
630         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
631         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
632             ->setAttributes(Attr_ReadOnly_NoUnwind);
633     }
634
635     // void[] _adSort(void[] a, TypeInfo ti)
636     {
637         llvm::StringRef fname("_adSort");
638         std::vector<const LLType*> types;
639         types.push_back(rt_array(byteTy));
640         types.push_back(typeInfoTy);
641         const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
642         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
643     }
644
645     /////////////////////////////////////////////////////////////////////////////////////
646     /////////////////////////////////////////////////////////////////////////////////////
647     /////////////////////////////////////////////////////////////////////////////////////
648
649     // size_t _aaLen(AA aa)
650     {
651         llvm::StringRef fname("_aaLen");
652         std::vector<const LLType*> types;
653         types.push_back(aaTy);
654         const llvm::FunctionType* fty = llvm::FunctionType::get(sizeTy, types, false);
655         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
656             ->setAttributes(Attr_ReadOnly_NoUnwind_1_NoCapture);
657     }
658
659     // void* _aaGet(AA* aa, TypeInfo keyti, size_t valuesize, void* pkey)
660     {
661         llvm::StringRef fname("_aaGet");
662         std::vector<const LLType*> types;
663         types.push_back(aaTy);
664         types.push_back(typeInfoTy);
665         types.push_back(sizeTy);
666         types.push_back(voidPtrTy);
667         const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
668         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
669             ->setAttributes(Attr_1_4_NoCapture);
670     }
671
672     // void* _aaIn(AA aa, TypeInfo keyti, void* pkey)
673     {
674         llvm::StringRef fname("_aaIn");
675         std::vector<const LLType*> types;
676         types.push_back(aaTy);
677         types.push_back(typeInfoTy);
678         types.push_back(voidPtrTy);
679         const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
680         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
681             ->setAttributes(Attr_ReadOnly_1_3_NoCapture);
682     }
683
684     // void _aaDel(AA aa, TypeInfo keyti, void* pkey)
685     {
686         llvm::StringRef fname("_aaDel");
687         std::vector<const LLType*> types;
688         types.push_back(aaTy);
689         types.push_back(typeInfoTy);
690         types.push_back(voidPtrTy);
691         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
692         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
693             ->setAttributes(Attr_1_3_NoCapture);
694     }
695
696     // void[] _aaValues(AA aa, size_t keysize, size_t valuesize)
697     {
698         llvm::StringRef fname("_aaValues");
699         std::vector<const LLType*> types;
700         types.push_back(aaTy);
701         types.push_back(sizeTy);
702         types.push_back(sizeTy);
703         const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
704         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
705             ->setAttributes(Attr_NoAlias_1_NoCapture);
706     }
707
708     // void* _aaRehash(AA* paa, TypeInfo keyti)
709     {
710         llvm::StringRef fname("_aaRehash");
711         std::vector<const LLType*> types;
712         types.push_back(aaTy);
713         types.push_back(typeInfoTy);
714         const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
715         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
716     }
717
718     // void[] _aaKeys(AA aa, size_t keysize)
719     {
720         llvm::StringRef fname("_aaKeys");
721         std::vector<const LLType*> types;
722         types.push_back(aaTy);
723         types.push_back(sizeTy);
724         const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
725         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
726             ->setAttributes(Attr_NoAlias_1_NoCapture);
727     }
728
729     // int _aaApply(AA aa, size_t keysize, dg_t dg)
730     {
731         llvm::StringRef fname("_aaApply");
732         std::vector<const LLType*> types;
733         types.push_back(aaTy);
734         types.push_back(sizeTy);
735         types.push_back(rt_dg1());
736         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
737         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
738             ->setAttributes(Attr_1_NoCapture);
739     }
740
741     // int _aaApply2(AA aa, size_t keysize, dg2_t dg)
742     {
743         llvm::StringRef fname("_aaApply2");
744         std::vector<const LLType*> types;
745         types.push_back(aaTy);
746         types.push_back(sizeTy);
747         types.push_back(rt_dg2());
748         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
749         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
750             ->setAttributes(Attr_1_NoCapture);
751     }
752
753     // int _aaEq(AA aa, AA ab, TypeInfo_AssociativeArray ti)
754     {
755         llvm::StringRef fname("_aaEq");
756         std::vector<const LLType*> types;
757         types.push_back(aaTy);
758         types.push_back(aaTy);
759         types.push_back(typeInfoTy);
760         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
761         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
762             ->setAttributes(Attr_1_2_NoCapture);
763     }
764
765     /////////////////////////////////////////////////////////////////////////////////////
766     /////////////////////////////////////////////////////////////////////////////////////
767     /////////////////////////////////////////////////////////////////////////////////////
768
769     // void _moduleCtor()
770     // void _moduleDtor()
771     {
772         llvm::StringRef fname("_moduleCtor");
773         llvm::StringRef fname2("_moduleDtor");
774         std::vector<const LLType*> types;
775         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
776         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
777         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
778     }
779
780     /////////////////////////////////////////////////////////////////////////////////////
781     /////////////////////////////////////////////////////////////////////////////////////
782     /////////////////////////////////////////////////////////////////////////////////////
783
784     // void _d_throw_exception(Object e)
785     {
786         llvm::StringRef fname("_d_throw_exception");
787         std::vector<const LLType*> types;
788         types.push_back(objectTy);
789         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
790         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
791     }
792
793     /////////////////////////////////////////////////////////////////////////////////////
794     /////////////////////////////////////////////////////////////////////////////////////
795     /////////////////////////////////////////////////////////////////////////////////////
796
797     // int _d_switch_string(char[][] table, char[] ca)
798     {
799         llvm::StringRef fname("_d_switch_string");
800         std::vector<const LLType*> types;
801         types.push_back(rt_array(stringTy));
802         types.push_back(stringTy);
803         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
804         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
805             ->setAttributes(Attr_ReadOnly);
806     }
807
808     // int _d_switch_ustring(wchar[][] table, wchar[] ca)
809     {
810         llvm::StringRef fname("_d_switch_ustring");
811         std::vector<const LLType*> types;
812         types.push_back(rt_array(wstringTy));
813         types.push_back(wstringTy);
814         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
815         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
816             ->setAttributes(Attr_ReadOnly);
817     }
818
819     // int _d_switch_dstring(dchar[][] table, dchar[] ca)
820     {
821         llvm::StringRef fname("_d_switch_dstring");
822         std::vector<const LLType*> types;
823         types.push_back(rt_array(dstringTy));
824         types.push_back(dstringTy);
825         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
826         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
827             ->setAttributes(Attr_ReadOnly);
828     }
829
830     /////////////////////////////////////////////////////////////////////////////////////
831     /////////////////////////////////////////////////////////////////////////////////////
832     /////////////////////////////////////////////////////////////////////////////////////
833
834     // void _d_criticalenter(D_CRITICAL_SECTION *dcs)
835     // void _d_criticalexit(D_CRITICAL_SECTION *dcs)
836     {
837         llvm::StringRef fname("_d_criticalenter");
838         llvm::StringRef fname2("_d_criticalexit");
839         std::vector<const LLType*> types;
840         types.push_back(rt_ptr(DtoMutexType()));
841         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
842         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
843         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
844     }
845
846     // void _d_monitorenter(Object h)
847     // void _d_monitorexit(Object h)
848     {
849         llvm::StringRef fname("_d_monitorenter");
850         llvm::StringRef fname2("_d_monitorexit");
851         std::vector<const LLType*> types;
852         types.push_back(objectTy);
853         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
854         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
855             ->setAttributes(Attr_1_NoCapture);
856         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)
857             ->setAttributes(Attr_1_NoCapture);
858     }
859
860     /////////////////////////////////////////////////////////////////////////////////////
861     /////////////////////////////////////////////////////////////////////////////////////
862     /////////////////////////////////////////////////////////////////////////////////////
863
864     // int _d_eh_personality(int ver, int actions, ulong eh_class, ptr eh_info, ptr context)
865     {
866         llvm::StringRef fname("_d_eh_personality");
867         std::vector<const LLType*> types;
868         types.push_back(intTy);
869         types.push_back(intTy);
870         types.push_back(longTy);
871         types.push_back(voidPtrTy);
872         types.push_back(voidPtrTy);
873         const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
874         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
875     }
876
877     // void _d_eh_resume_unwind(ptr exc_struct)
878     {
879         llvm::StringRef fname("_d_eh_resume_unwind");
880         std::vector<const LLType*> types;
881         types.push_back(voidPtrTy);
882         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
883         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
884     }
885
886     /////////////////////////////////////////////////////////////////////////////////////
887     /////////////////////////////////////////////////////////////////////////////////////
888     /////////////////////////////////////////////////////////////////////////////////////
889
890     // void _d_invariant(Object o)
891     {
892         llvm::StringRef fname("_d_invariant");
893         std::vector<const LLType*> types;
894         types.push_back(objectTy);
895         const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
896         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
897     }
898 }
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.