//===-- gen/irstate.h - Global codegen state --------------------*- C++ -*-===// // // LDC – the LLVM D compiler // // This file is distributed under the BSD-style LDC license. See the LICENSE // file for details. // //===----------------------------------------------------------------------===// // // This file contains the global state used and modified when generating the // code (i.e. LLVM IR) for a given D module. // //===----------------------------------------------------------------------===// #ifndef LDC_GEN_IRSTATE_H #define LDC_GEN_IRSTATE_H #include "aggregate.h" #include "root.h" #include "ir/iraggr.h" #include "ir/irvar.h" #include "gen/dibuilder.h" #include #include #include #include #include #include "llvm/ADT/StringMap.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/IR/CallSite.h" namespace llvm { class LLVMContext; class TargetMachine; class IndexedInstrProfReader; } // global ir state for current module struct IRState; struct TargetABI; extern IRState *gIR; extern llvm::TargetMachine *gTargetMachine; extern const llvm::DataLayout *gDataLayout; extern TargetABI *gABI; class TypeFunction; class TypeStruct; class ClassDeclaration; class FuncDeclaration; class Module; class TypeStruct; struct BaseClass; class AnonDeclaration; struct IrFunction; struct IrModule; // represents a scope struct IRScope { llvm::BasicBlock *begin; IRBuilder<> builder; IRScope(); explicit IRScope(llvm::BasicBlock *b); IRScope &operator=(const IRScope &rhs); }; struct IRBuilderHelper { IRState *state; IRBuilder<> *operator->(); }; struct IRAsmStmt { IRAsmStmt() : isBranchToLabel(nullptr) {} std::string code; std::string out_c; std::string in_c; std::vector out; std::vector in; // if this is nonzero, it contains the target label LabelDsymbol *isBranchToLabel; }; struct IRAsmBlock { std::deque s; std::set clobs; size_t outputcount; // stores the labels within the asm block std::vector internalLabels; CompoundAsmStatement *asmBlock; LLType *retty; unsigned retn; bool retemu; // emulate abi ret with a temporary LLValue *(*retfixup)(IRBuilderHelper b, LLValue *orig); // Modifies retval explicit IRAsmBlock(CompoundAsmStatement *b) : outputcount(0), asmBlock(b), retty(nullptr), retn(0), retemu(false), retfixup(nullptr) {} }; // represents the module struct IRState { IRState(const char *name, llvm::LLVMContext &context); llvm::Module module; llvm::LLVMContext &context() const { return module.getContext(); } Module *dmodule; LLStructType *mutexType; LLStructType *moduleRefType; // functions typedef std::vector FunctionVector; FunctionVector functions; IrFunction *func(); llvm::Function *topfunc(); llvm::Instruction *topallocapoint(); // The function containing the D main() body, if any (not the actual main() // implicitly emitted). llvm::Function *mainFunc; // basic block scopes std::vector scopes; IRScope &scope(); llvm::BasicBlock *scopebb(); bool scopereturned(); // create a call or invoke, depending on the landing pad info llvm::CallSite CreateCallOrInvoke(LLValue *Callee, const char *Name = ""); llvm::CallSite CreateCallOrInvoke(LLValue *Callee, LLValue *Arg1, const char *Name = ""); llvm::CallSite CreateCallOrInvoke(LLValue *Callee, LLValue *Arg1, LLValue *Arg2, const char *Name = ""); llvm::CallSite CreateCallOrInvoke(LLValue *Callee, LLValue *Arg1, LLValue *Arg2, LLValue *Arg3, const char *Name = ""); llvm::CallSite CreateCallOrInvoke(LLValue *Callee, LLValue *Arg1, LLValue *Arg2, LLValue *Arg3, LLValue *Arg4, const char *Name = ""); // 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 arrays; // builder helper IRBuilderHelper ir; // debug info helper ldc::DIBuilder DBuilder; // PGO data file reader std::unique_ptr PGOReader; llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); } // for inline asm IRAsmBlock *asmBlock; std::ostringstream nakedAsm; // Globals to pin in the llvm.used array to make sure they are not // eliminated. std::vector usedArray; /// Whether to emit array bounds checking in the current function. bool emitArrayBoundsChecks(); // Global variables bound to string literals. Once created such a // variable is reused whenever the same string literal is // referenced in the module. Caching them per module prevents the // duplication of identical literals. llvm::StringMap stringLiteral1ByteCache; llvm::StringMap stringLiteral2ByteCache; llvm::StringMap stringLiteral4ByteCache; /// Vector of options passed to the linker as metadata in object file. #if LDC_LLVM_VER >= 306 llvm::SmallVector LinkerMetadataArgs; #else llvm::SmallVector LinkerMetadataArgs; #endif #if LDC_LLVM_VER >= 308 // MS C++ compatible type descriptors llvm::DenseMap TypeDescriptorTypeMap; llvm::DenseMap TypeDescriptorMap; #endif }; void Statement_toIR(Statement *s, IRState *irs); #endif // LDC_GEN_IRSTATE_H