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

root/gen/irstate.h

Revision 1571:8d086d552909, 6.4 kB (checked in by Benjamin Kramer <benny.kra@gmail.com>, 3 years ago)

IntegerType? is now contextifed.

Requires llvm >= 78969. resistor says this will be the last context API change :)

Line 
1 #ifndef LDC_GEN_IRSTATE_H
2 #define LDC_GEN_IRSTATE_H
3
4 #include <vector>
5 #include <deque>
6 #include <list>
7 #include <sstream>
8
9 #include "root.h"
10 #include "aggregate.h"
11
12 #include "ir/irfunction.h"
13 #include "ir/irstruct.h"
14 #include "ir/irvar.h"
15
16 #include "llvm/Support/CallSite.h"
17
18 namespace llvm {
19     class LLVMContext;
20     class TargetMachine;
21 }
22
23 // global ir state for current module
24 struct IRState;
25 struct TargetABI;
26
27 extern IRState* gIR;
28 extern llvm::TargetMachine* gTargetMachine;
29 extern const llvm::TargetData* gTargetData;
30 extern TargetABI* gABI;
31
32 struct TypeFunction;
33 struct TypeStruct;
34 struct ClassDeclaration;
35 struct FuncDeclaration;
36 struct Module;
37 struct TypeStruct;
38 struct BaseClass;
39 struct AnonDeclaration;
40
41 struct IrModule;
42
43 // represents a scope
44 struct IRScope
45 {
46     llvm::BasicBlock* begin;
47     llvm::BasicBlock* end;
48     IRBuilder<> builder;
49
50     IRScope();
51     IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e);
52    
53     const IRScope& operator=(const IRScope& rhs);
54 };
55
56 struct IRBuilderHelper
57 {
58     IRState* state;
59     IRBuilder<>* operator->();
60 };
61
62 struct IRAsmStmt
63 {
64     IRAsmStmt()
65     : isBranchToLabel(NULL) {}
66
67     std::string code;
68     std::string out_c;
69     std::string in_c;
70     std::vector<LLValue*> out;
71     std::vector<LLValue*> in;
72
73     // if this is nonzero, it contains the target label
74     Identifier* isBranchToLabel;
75 };
76
77 struct IRAsmBlock
78 {
79     std::deque<IRAsmStmt*> s;
80     std::set<std::string> clobs;
81     size_t outputcount;
82
83     // stores the labels within the asm block
84     std::vector<Identifier*> internalLabels;
85
86     AsmBlockStatement* asmBlock;
87     const LLType* retty;
88     unsigned retn;
89     bool retemu; // emulate abi ret with a temporary
90     LLValue* (*retfixup)(IRBuilderHelper b, LLValue* orig); // Modifies retval
91
92     IRAsmBlock(AsmBlockStatement* b)
93         : asmBlock(b), retty(NULL), retn(0), retemu(false), retfixup(NULL),
94           outputcount(0)
95     {}
96 };
97
98 // represents the module
99 struct IRState
100 {
101     IRState(llvm::Module* m);
102
103     // module
104     Module* dmodule;
105     llvm::Module* module;
106
107     // interface info type, used in DtoInterfaceInfoType
108     const LLStructType* interfaceInfoType;
109     const LLStructType* mutexType;
110     const LLStructType* moduleRefType;
111
112     // helper to get the LLVMContext of the module
113     llvm::LLVMContext& context() const { return module->getContext(); }
114
115     // functions
116     typedef std::vector<IrFunction*> FunctionVector;
117     FunctionVector functions;
118     IrFunction* func();
119
120     llvm::Function* topfunc();
121     TypeFunction* topfunctype();
122     llvm::Instruction* topallocapoint();
123
124     // structs
125     typedef std::vector<IrStruct*> StructVector;
126     StructVector structs;
127     IrStruct* topstruct();
128
129     // D main function
130     bool emitMain;
131     llvm::Function* mainFunc;
132
133     // basic block scopes
134     std::vector<IRScope> scopes;
135     IRScope& scope();
136     llvm::BasicBlock* scopebb();
137     llvm::BasicBlock* scopeend();
138     bool scopereturned();
139
140     // create a call or invoke, depending on the landing pad info
141     // the template function is defined further down in this file
142     template <typename InputIterator>
143     llvm::CallSite CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name="");
144     llvm::CallSite CreateCallOrInvoke(LLValue* Callee, const char* Name="");
145     llvm::CallSite CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name="");
146     llvm::CallSite CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name="");
147     llvm::CallSite CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name="");
148     llvm::CallSite CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2,  LLValue* Arg3, LLValue* Arg4, const char* Name="");
149
150     // this holds the array being indexed or sliced so $ will work
151     // might be a better way but it works. problem is I only get a
152     // VarDeclaration for __dollar, but I can't see how to get the
153     // array pointer from this :(
154     std::vector<DValue*> arrays;
155
156     // builder helper
157     IRBuilderHelper ir;
158
159     // debug info helper
160     llvm::DIFactory difactory;
161
162     // static ctors/dtors/unittests
163     typedef std::vector<FuncDeclaration*> FuncDeclVector;
164     FuncDeclVector ctors;
165     FuncDeclVector dtors;
166     FuncDeclVector unitTests;
167    
168     // all template instances that had members emitted
169     // currently only filled for singleobj
170     // used to make sure the complete template instance gets emitted in the
171     // first file that touches a member, see #318
172     typedef std::set<TemplateInstance*> TemplateInstanceSet;
173     TemplateInstanceSet seenTemplateInstances;
174
175     // for inline asm
176     IRAsmBlock* asmBlock;
177     std::ostringstream nakedAsm;
178
179     // 'used' array solely for keeping a reference to globals
180     std::vector<LLConstant*> usedArray;
181
182     // dwarf dbg stuff
183     LLGlobalVariable* dwarfCUs;
184     LLGlobalVariable* dwarfSPs;
185     LLGlobalVariable* dwarfGVs;
186 };
187
188 template <typename InputIterator>
189 llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name)
190 {
191     llvm::BasicBlock* pad = func()->gen->landingPad;
192     if(pad)
193     {
194         // intrinsics don't support invoking and 'nounwind' functions don't need it.
195         LLFunction* funcval = llvm::dyn_cast<LLFunction>(Callee);
196         if (funcval && (funcval->isIntrinsic() || funcval->doesNotThrow()))
197         {
198             llvm::CallInst* call = ir->CreateCall(Callee, ArgBegin, ArgEnd, Name);
199             call->setAttributes(funcval->getAttributes());
200             return call;
201         }
202
203         llvm::BasicBlock* postinvoke = llvm::BasicBlock::Create(gIR->context(), "postinvoke", topfunc(), scopeend());
204         llvm::InvokeInst* invoke = ir->CreateInvoke(Callee, postinvoke, pad, ArgBegin, ArgEnd, Name);
205         if (LLFunction* fn = llvm::dyn_cast<LLFunction>(Callee))
206             invoke->setAttributes(fn->getAttributes());
207         scope() = IRScope(postinvoke, scopeend());
208         return invoke;
209     }
210     else
211     {
212         llvm::CallInst* call = ir->CreateCall(Callee, ArgBegin, ArgEnd, Name);
213         if (LLFunction* fn = llvm::dyn_cast<LLFunction>(Callee))
214             call->setAttributes(fn->getAttributes());
215         return call;
216     }
217 }
218
219 #endif // LDC_GEN_IRSTATE_H
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.