#pragma once #include "BfIRBuilder.h" #include "BfSystem.h" #include "BfTargetTriple.h" namespace llvm { class Constant; class Value; class Type; class BasicBlock; class Function; class FunctionType; class MDNode; class InlineAsm; class DIType; class DIBuilder; class DICompileUnit; class AttributeList; class Module; class LLVMContext; class TargetMachine; }; NS_BF_BEGIN enum BfIRCodeGenEntryKind { BfIRCodeGenEntryKind_None, BfIRCodeGenEntryKind_LLVMValue, BfIRCodeGenEntryKind_LLVMType, BfIRCodeGenEntryKind_LLVMBasicBlock, BfIRCodeGenEntryKind_LLVMMetadata, BfIRCodeGenEntryKind_IntrinsicData, }; class BfIRIntrinsicData { public: String mName; BfIRIntrinsic mIntrinsic; llvm::Type* mReturnType; }; struct BfIRCodeGenEntry { BfIRCodeGenEntryKind mKind; union { llvm::Value* mLLVMValue; llvm::Type* mLLVMType; llvm::BasicBlock* mLLVMBlock; llvm::MDNode* mLLVMMetadata; BfIRIntrinsicData* mIntrinsicData; }; }; class BfIRTypeEntry { public: int mTypeId; llvm::DIType* mDIType; llvm::DIType* mInstDIType; llvm::Type* mLLVMType; llvm::Type* mInstLLVMType; public: BfIRTypeEntry() { mTypeId = -1; mDIType = NULL; mInstDIType = NULL; mLLVMType = NULL; mInstLLVMType = NULL; } }; class BfIRCodeGen : public BfIRCodeGenBase { public: BfIRBuilder* mBfIRBuilder; BumpAllocator mAlloc; BfTargetTriple mTargetTriple; String mModuleName; llvm::LLVMContext* mLLVMContext; llvm::Module* mLLVMModule; llvm::Function* mActiveFunction; llvm::IRBuilder<>* mIRBuilder; llvm::AttributeList* mAttrSet; llvm::DIBuilder* mDIBuilder; llvm::DICompileUnit* mDICompileUnit; llvm::TargetMachine* mLLVMTargetMachine; Array mSavedDebugLocs; llvm::InlineAsm* mNopInlineAsm; llvm::InlineAsm* mAsmObjectCheckAsm; llvm::DebugLoc mDebugLoc; BfCodeGenOptions mCodeGenOptions; bool mHasDebugLoc; bool mIsCodeView; int mConstValIdx; int mCmdCount; Dictionary mResults; Dictionary mTypes; Dictionary mIntrinsicMap; Dictionary mIntrinsicReverseMap; Array mConfigConsts32; Array mConfigConsts64; Dictionary mReflectDataMap; public: void InitTarget(); void FixValues(llvm::StructType* structType, llvm::SmallVector& values); BfTypeCode GetTypeCode(llvm::Type* type, bool isSigned); llvm::Type* GetLLVMType(BfTypeCode typeCode, bool& isSigned); BfIRTypeEntry& GetTypeEntry(int typeId); void SetResult(int id, llvm::Value* value); void SetResult(int id, llvm::Type* value); void SetResult(int id, llvm::BasicBlock* value); void SetResult(int id, llvm::MDNode* value); void CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile = false); void AddNop(); llvm::Value* TryToVector(llvm::Value* value); llvm::Value* TryToVector(llvm::Value* value, llvm::Type* elemType); llvm::Type* GetElemType(llvm::Value* value); bool TryMemCpy(llvm::Value* ptr, llvm::Value* val); bool TryVectorCpy(llvm::Value* ptr, llvm::Value* val); public: BfIRCodeGen(); ~BfIRCodeGen(); void FatalError(const StringImpl& str); virtual void Fail(const StringImpl& error) override; void ProcessBfIRData(const BfSizedArray& buffer) override; void PrintModule(); void PrintFunction(); int64 ReadSLEB128(); void Read(StringImpl& str); void Read(int& i); void Read(int64& i); void Read(Val128& i); void Read(bool& val); void Read(BfIRTypeEntry*& type); void Read(llvm::Type*& llvmType); void Read(llvm::FunctionType*& llvmType); void Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL); void Read(llvm::Constant*& llvmConstant); void Read(llvm::Function*& llvmFunc); void Read(llvm::BasicBlock*& llvmBlock); void Read(llvm::MDNode*& llvmMD); void Read(llvm::Metadata*& llvmMD); template void Read(llvm::SmallVectorImpl& vec) { int len = (int)ReadSLEB128(); for (int i = 0; i < len; i++) { T result; Read(result); vec.push_back(result); } } void HandleNextCmd() override; void SetCodeGenOptions(BfCodeGenOptions codeGenOptions); void SetConfigConst(int idx, int value) override; llvm::Value* GetLLVMValue(int streamId); llvm::Type* GetLLVMType(int streamId); llvm::BasicBlock* GetLLVMBlock(int streamId); llvm::MDNode* GetLLVMMetadata(int streamId); llvm::Type* GetLLVMTypeById(int id); /// bool WriteObjectFile(const StringImpl& outFileName); bool WriteIR(const StringImpl& outFileName, StringImpl& error); static int GetIntrinsicId(const StringImpl& name); static const char* GetIntrinsicName(int intrinId); static void SetAsmKind(BfAsmKind asmKind); static void StaticInit(); }; NS_BF_END