1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-07 19:18:19 +02:00
Beef/IDEHelper/Compiler/BfIRCodeGen.h
2025-03-20 09:25:46 -04:00

310 lines
8.2 KiB
C++

#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;
class Triple;
};
NS_BF_BEGIN
enum BfIRCodeGenEntryKind
{
BfIRCodeGenEntryKind_None,
BfIRCodeGenEntryKind_LLVMValue,
BfIRCodeGenEntryKind_LLVMValue_Aligned,
BfIRCodeGenEntryKind_LLVMType,
BfIRCodeGenEntryKind_TypedValue,
BfIRCodeGenEntryKind_TypedValue_Aligned,
BfIRCodeGenEntryKind_TypeEx,
BfIRCodeGenEntryKind_LLVMBasicBlock,
BfIRCodeGenEntryKind_LLVMMetadata,
BfIRCodeGenEntryKind_IntrinsicData,
};
class BfIRTypeEx;
class BfIRIntrinsicData
{
public:
String mName;
BfIRIntrinsic mIntrinsic;
BfIRTypeEx* mReturnType;
};
class BfIRTypeEx
{
public:
llvm::Type* mLLVMType;
SizedArray<BfIRTypeEx*, 1> mMembers;
BfIRTypeEx()
{
mLLVMType = NULL;
}
};
struct BfIRTypedValue
{
llvm::Value* mValue;
BfIRTypeEx* mTypeEx;
};
struct BfIRCodeGenEntry
{
BfIRCodeGenEntryKind mKind;
union
{
llvm::Value* mLLVMValue;
llvm::Type* mLLVMType;
BfIRTypeEx* mTypeEx;
llvm::BasicBlock* mLLVMBlock;
llvm::MDNode* mLLVMMetadata;
BfIRIntrinsicData* mIntrinsicData;
BfIRTypedValue mTypedValue;
};
};
class BfIRTypeEntry
{
public:
int mTypeId;
int mSize;
int mAlign;
llvm::DIType* mDIType;
llvm::DIType* mInstDIType;
BfIRTypeEx* mType;
BfIRTypeEx* mAlignType;
BfIRTypeEx* mInstType;
public:
BfIRTypeEntry()
{
mTypeId = -1;
mSize = -1;
mAlign = -1;
mDIType = NULL;
mInstDIType = NULL;
mType = NULL;
mAlignType = NULL;
mInstType = NULL;
}
};
enum BfIRSizeAlignKind
{
BfIRSizeAlignKind_NoTransform,
BfIRSizeAlignKind_Original,
BfIRSizeAlignKind_Aligned,
};
enum BfIRSimdType
{
BfIRSimdType_None,
BfIRSimdType_SSE,
BfIRSimdType_SSE2,
BfIRSimdType_AVX,
BfIRSimdType_AVX2,
BfIRSimdType_AVX512
};
class BfIRCodeGen : public BfIRCodeGenBase
{
public:
BfIRBuilder* mBfIRBuilder;
BumpAllocator mAlloc;
BfTargetTriple mTargetTriple;
String mTargetCPU;
String mModuleName;
llvm::LLVMContext* mLLVMContext;
llvm::Module* mLLVMModule;
llvm::Function* mActiveFunction;
BfIRTypeEx* mActiveFunctionType;
llvm::IRBuilder<>* mIRBuilder;
llvm::AttributeList* mAttrSet;
llvm::DIBuilder* mDIBuilder;
llvm::DICompileUnit* mDICompileUnit;
llvm::TargetMachine* mLLVMTargetMachine;
Array<llvm::DebugLoc> mSavedDebugLocs;
llvm::InlineAsm* mNopInlineAsm;
llvm::InlineAsm* mObjectCheckAsm;
llvm::InlineAsm* mOverflowCheckAsm;
llvm::DebugLoc mDebugLoc;
BfCodeGenOptions mCodeGenOptions;
bool mHasDebugLoc;
bool mIsCodeView;
bool mHadDLLExport;
int mConstValIdx;
int mCmdCount;
int mCurLine;
Dictionary<int, BfIRCodeGenEntry> mResults;
Dictionary<int, BfIRTypeEntry> mTypes;
Dictionary<int, llvm::Function*> mIntrinsicMap;
Dictionary<BfTypeCode, BfIRTypeEx*> mTypeCodeTypeExMap;
Dictionary<llvm::Type*, BfIRTypeEx*> mLLVMTypeExMap;
Dictionary<BfIRTypeEx*, BfIRTypeEx*> mPointerTypeExMap;
Dictionary<llvm::Function*, int> mIntrinsicReverseMap;
Array<llvm::Constant*> mConfigConsts32;
Array<llvm::Constant*> mConfigConsts64;
Dictionary<BfIRTypeEx*, BfIRTypedValue> mReflectDataMap;
Dictionary<BfIRTypeEx*, BfIRTypeEx*> mAlignedTypeToNormalType;
Dictionary<BfIRTypeEx*, int> mTypeToTypeIdMap;
HashSet<llvm::BasicBlock*> mLockedBlocks;
OwnedArray<BfIRIntrinsicData> mIntrinsicData;
Dictionary<llvm::Function*, BfIRSimdType> mFunctionsUsingSimd;
Array<BfIRTypeEx*> mIRTypeExs;
BfIRTypedValue mLastFuncCalled;
public:
void InitTarget();
void FixValues(llvm::StructType* structType, llvm::SmallVector<llvm::Value*, 8>& values);
void FixIndexer(llvm::Value*& val);
void FixTypedValue(BfIRTypedValue& typedValue);
BfTypeCode GetTypeCode(llvm::Type* type, bool isSigned);
llvm::Type* GetLLVMType(BfTypeCode typeCode, bool& isSigned);
BfIRTypeEx* GetTypeEx(llvm::Type* llvmType);
BfIRTypeEx* CreateTypeEx(llvm::Type* llvmType);
BfIRTypeEx* GetTypeEx(BfTypeCode typeCode, bool& isSigned);
BfIRTypeEx* GetPointerTypeEx(BfIRTypeEx* typeEx);
BfIRTypeEx* GetTypeMember(BfIRTypeEx* typeEx, int idx);
BfIRTypeEntry& GetTypeEntry(int typeId);
BfIRTypeEntry* GetTypeEntry(BfIRTypeEx* type);
void SetResult(int id, llvm::Value* value);
void SetResult(int id, const BfIRTypedValue& value);
void SetResultAligned(int id, llvm::Value* value);
void SetResultAligned(int id, const BfIRTypedValue& value);
void SetResult(int id, llvm::Type* value);
void SetResult(int id, BfIRTypeEx* typeEx);
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(const BfIRTypedValue& value);
bool TryMemCpy(const BfIRTypedValue& ptr, llvm::Value* val);
bool TryVectorCpy(const BfIRTypedValue& ptr, llvm::Value* val);
llvm::Type* GetLLVMPointerElementType(BfIRTypeEx* typeEx);
BfIRTypeEx* GetSizeAlignedType(BfIRTypeEntry* typeEntry);
BfIRTypedValue GetAlignedPtr(const BfIRTypedValue& val);
llvm::Value* DoCheckedIntrinsic(llvm::Intrinsic::ID intrin, llvm::Value* lhs, llvm::Value* rhs, bool useAsm);
void RunOptimizationPipeline(const llvm::Triple& targetTriple);
public:
BfIRCodeGen();
~BfIRCodeGen();
void FatalError(const StringImpl& str);
virtual void Fail(const StringImpl& error) override;
void ProcessBfIRData(const BfSizedArray<uint8>& 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(int8& val);
void Read(BfIRTypeEntry*& type);
void Read(BfIRTypeEx*& typeEx, BfIRTypeEntry** outTypeEntry = NULL);
void Read(llvm::Type*& llvmType, BfIRTypeEntry** outTypeEntry = NULL);
void Read(llvm::FunctionType*& llvmType);
void ReadFunctionType(BfIRTypeEx*& typeEx);
void Read(BfIRTypedValue& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original);
void Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original);
void Read(llvm::Constant*& llvmConstant, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original);
void Read(llvm::Function*& llvmFunc);
void ReadFunction(BfIRTypedValue& typeEx);
void Read(llvm::BasicBlock*& llvmBlock);
void Read(llvm::MDNode*& llvmMD);
void Read(llvm::Metadata*& llvmMD);
template <typename T>
void Read(llvm::SmallVectorImpl<T>& vec)
{
int len = (int)ReadSLEB128();
for (int i = 0; i < len; i++)
{
T result;
Read(result);
vec.push_back(result);
}
}
void Read(llvm::SmallVectorImpl<llvm::Value*>& vec, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original)
{
int len = (int)ReadSLEB128();
for (int i = 0; i < len; i++)
{
llvm::Value* result;
Read(result, NULL, sizeAlignKind);
vec.push_back(result);
}
}
void Read(llvm::SmallVectorImpl<llvm::Constant*>& vec, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original)
{
int len = (int)ReadSLEB128();
for (int i = 0; i < len; i++)
{
llvm::Constant* result;
Read(result, sizeAlignKind);
vec.push_back(result);
}
}
void HandleNextCmd() override;
void SetCodeGenOptions(BfCodeGenOptions codeGenOptions);
void SetConfigConst(int idx, int value) override;
void SetActiveFunctionSimdType(BfIRSimdType type);
String GetSimdTypeString(BfIRSimdType type);
BfIRSimdType GetSimdTypeFromFunction(llvm::Function* function);
BfIRTypedValue GetTypedValue(int streamId);
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);
void ApplySimdFeatures();
static int GetIntrinsicId(const StringImpl& name);
static const char* GetIntrinsicName(int intrinId);
static void SetAsmKind(BfAsmKind asmKind);
static void StaticInit();
};
NS_BF_END