Mercurial > projects > ldc
view gen/irstate.h @ 1015:799dbdf9c461
Same fix for align size of void type on D2.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sun, 01 Mar 2009 01:34:20 +0100 |
parents | 8c73ff5f69e0 |
children | f99a3b393c03 |
line wrap: on
line source
#ifndef LDC_GEN_IRSTATE_H #define LDC_GEN_IRSTATE_H #include <vector> #include <deque> #include <list> #include <sstream> #include "root.h" #include "aggregate.h" #include "ir/irfunction.h" #include "ir/irstruct.h" #include "ir/irvar.h" #include "llvm/Support/CallSite.h" namespace llvm { class TargetMachine; } // global ir state for current module struct IRState; struct TargetABI; extern IRState* gIR; extern llvm::TargetMachine* gTargetMachine; extern const llvm::TargetData* gTargetData; extern TargetABI* gABI; struct TypeFunction; struct TypeStruct; struct ClassDeclaration; struct FuncDeclaration; struct Module; struct TypeStruct; struct BaseClass; struct AnonDeclaration; struct EnclosingHandler; struct IrModule; // represents a scope struct IRScope { llvm::BasicBlock* begin; llvm::BasicBlock* end; IRBuilder<> builder; IRScope(); IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e); }; // scope for loops struct IRLoopScope : IRScope { // generating statement Statement* s; // the try of a TryFinally that encloses the loop EnclosingHandler* enclosinghandler; // if it is a switch, we are a possible target for break // but not for continue bool isSwitch; IRLoopScope(); IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e, bool isSwitch = false); }; struct IRBuilderHelper { IRState* state; IRBuilder<>* operator->(); }; struct IRAsmStmt { IRAsmStmt() : isBranchToLabel(NULL) {} std::string code; std::string out_c; std::string in_c; std::vector<LLValue*> out; std::vector<LLValue*> in; // if this is nonzero, it contains the target label Identifier* isBranchToLabel; }; struct IRAsmBlock { std::deque<IRAsmStmt*> s; std::set<std::string> clobs; size_t outputcount; // stores the labels within the asm block std::vector<Identifier*> internalLabels; AsmBlockStatement* asmBlock; const LLType* retty; unsigned retn; bool retemu; // emulate abi ret with a temporary LLValue* (*retfixup)(IRBuilderHelper b, LLValue* orig); // Modifies retval IRAsmBlock(AsmBlockStatement* b) : asmBlock(b), retty(NULL), retn(0), retemu(false), retfixup(NULL), outputcount(0) {} }; // represents the module struct IRState { IRState(llvm::Module* m); // module Module* dmodule; llvm::Module* module; // interface info type, used in DtoInterfaceInfoType const LLStructType* interfaceInfoType; const LLStructType* mutexType; const LLStructType* moduleRefType; // functions typedef std::vector<IrFunction*> FunctionVector; FunctionVector functions; IrFunction* func(); llvm::Function* topfunc(); TypeFunction* topfunctype(); llvm::Instruction* topallocapoint(); // structs typedef std::vector<IrStruct*> StructVector; StructVector structs; IrStruct* topstruct(); // D main function bool emitMain; llvm::Function* mainFunc; // basic block scopes std::vector<IRScope> scopes; IRScope& scope(); llvm::BasicBlock* scopebb(); llvm::BasicBlock* scopeend(); bool scopereturned(); // create a call or invoke, depending on the landing pad info // the template function is defined further down in this file template <typename InputIterator> llvm::CallSite CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name=""); llvm::CallSite CreateCallOrInvoke(LLValue* Callee, const char* Name=""); llvm::CallSite CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name=""); llvm::CallSite CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name=""); llvm::CallSite CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name=""); llvm::CallSite CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, LLValue* Arg4, const char* Name=""); // loop blocks typedef std::vector<IRLoopScope> LoopScopeVec; LoopScopeVec loopbbs; // this holds the array being indexed or sliced so $ will work // might be a better way but it works. problem is I only get a // VarDeclaration for __dollar, but I can't see how to get the // array pointer from this :( std::vector<DValue*> arrays; // builder helper IRBuilderHelper ir; // debug info helper llvm::DIFactory difactory; typedef std::list<Dsymbol*> DsymbolList; // dsymbols that need to be resolved DsymbolList resolveList; // dsymbols that need to be declared DsymbolList declareList; // dsymbols that need constant initializers constructed DsymbolList constInitList; // dsymbols that need definitions DsymbolList defineList; // static ctors/dtors/unittests typedef std::vector<FuncDeclaration*> FuncDeclVector; FuncDeclVector ctors; FuncDeclVector dtors; FuncDeclVector unitTests; // for inline asm IRAsmBlock* asmBlock; std::ostringstream nakedAsm; // 'used' array solely for keeping a reference to globals std::vector<LLConstant*> usedArray; // dwarf dbg stuff LLGlobalVariable* dwarfCUs; LLGlobalVariable* dwarfSPs; LLGlobalVariable* dwarfGVs; }; template <typename InputIterator> llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name) { llvm::BasicBlock* pad; if(pad = func()->landingPad.get()) { // intrinsics don't support invoking LLFunction* funcval = llvm::dyn_cast<LLFunction>(Callee); if (funcval && funcval->isIntrinsic()) { return ir->CreateCall(Callee, ArgBegin, ArgEnd, Name); } llvm::BasicBlock* postinvoke = llvm::BasicBlock::Create("postinvoke", topfunc(), scopeend()); llvm::InvokeInst* invoke = ir->CreateInvoke(Callee, postinvoke, pad, ArgBegin, ArgEnd, Name); scope() = IRScope(postinvoke, scopeend()); return invoke; } else return ir->CreateCall(Callee, ArgBegin, ArgEnd, Name); } #endif // LDC_GEN_IRSTATE_H