BfIRCodeGen.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #pragma once
  2. #include "BfIRBuilder.h"
  3. #include "BfSystem.h"
  4. #include "BfTargetTriple.h"
  5. namespace llvm
  6. {
  7. class Constant;
  8. class Value;
  9. class Type;
  10. class BasicBlock;
  11. class Function;
  12. class FunctionType;
  13. class MDNode;
  14. class InlineAsm;
  15. class DIType;
  16. class DIBuilder;
  17. class DICompileUnit;
  18. class AttributeList;
  19. class Module;
  20. class LLVMContext;
  21. class TargetMachine;
  22. class Triple;
  23. };
  24. NS_BF_BEGIN
  25. enum BfIRCodeGenEntryKind
  26. {
  27. BfIRCodeGenEntryKind_None,
  28. BfIRCodeGenEntryKind_LLVMValue,
  29. BfIRCodeGenEntryKind_LLVMValue_Aligned,
  30. BfIRCodeGenEntryKind_LLVMType,
  31. BfIRCodeGenEntryKind_TypedValue,
  32. BfIRCodeGenEntryKind_TypedValue_Aligned,
  33. BfIRCodeGenEntryKind_TypeEx,
  34. BfIRCodeGenEntryKind_LLVMBasicBlock,
  35. BfIRCodeGenEntryKind_LLVMMetadata,
  36. BfIRCodeGenEntryKind_IntrinsicData,
  37. };
  38. class BfIRTypeEx;
  39. class BfIRIntrinsicData
  40. {
  41. public:
  42. String mName;
  43. BfIRIntrinsic mIntrinsic;
  44. BfIRTypeEx* mReturnType;
  45. };
  46. class BfIRTypeEx
  47. {
  48. public:
  49. llvm::Type* mLLVMType;
  50. SizedArray<BfIRTypeEx*, 1> mMembers;
  51. BfIRTypeEx()
  52. {
  53. mLLVMType = NULL;
  54. }
  55. };
  56. struct BfIRTypedValue
  57. {
  58. llvm::Value* mValue;
  59. BfIRTypeEx* mTypeEx;
  60. };
  61. struct BfIRCodeGenEntry
  62. {
  63. BfIRCodeGenEntryKind mKind;
  64. union
  65. {
  66. llvm::Value* mLLVMValue;
  67. llvm::Type* mLLVMType;
  68. BfIRTypeEx* mTypeEx;
  69. llvm::BasicBlock* mLLVMBlock;
  70. llvm::MDNode* mLLVMMetadata;
  71. BfIRIntrinsicData* mIntrinsicData;
  72. BfIRTypedValue mTypedValue;
  73. };
  74. };
  75. class BfIRTypeEntry
  76. {
  77. public:
  78. int mTypeId;
  79. int mSize;
  80. int mAlign;
  81. llvm::DIType* mDIType;
  82. llvm::DIType* mInstDIType;
  83. BfIRTypeEx* mType;
  84. BfIRTypeEx* mAlignType;
  85. BfIRTypeEx* mInstType;
  86. public:
  87. BfIRTypeEntry()
  88. {
  89. mTypeId = -1;
  90. mSize = -1;
  91. mAlign = -1;
  92. mDIType = NULL;
  93. mInstDIType = NULL;
  94. mType = NULL;
  95. mAlignType = NULL;
  96. mInstType = NULL;
  97. }
  98. };
  99. enum BfIRSizeAlignKind
  100. {
  101. BfIRSizeAlignKind_NoTransform,
  102. BfIRSizeAlignKind_Original,
  103. BfIRSizeAlignKind_Aligned,
  104. };
  105. enum BfIRSimdType
  106. {
  107. BfIRSimdType_None,
  108. BfIRSimdType_SSE,
  109. BfIRSimdType_SSE2,
  110. BfIRSimdType_AVX,
  111. BfIRSimdType_AVX2,
  112. BfIRSimdType_AVX512
  113. };
  114. class BfIRCodeGen : public BfIRCodeGenBase
  115. {
  116. public:
  117. BfIRBuilder* mBfIRBuilder;
  118. BumpAllocator mAlloc;
  119. BfTargetTriple mTargetTriple;
  120. String mTargetCPU;
  121. String mModuleName;
  122. llvm::LLVMContext* mLLVMContext;
  123. llvm::Module* mLLVMModule;
  124. llvm::Function* mActiveFunction;
  125. BfIRTypeEx* mActiveFunctionType;
  126. llvm::IRBuilder<>* mIRBuilder;
  127. llvm::AttributeList* mAttrSet;
  128. llvm::DIBuilder* mDIBuilder;
  129. llvm::DICompileUnit* mDICompileUnit;
  130. llvm::TargetMachine* mLLVMTargetMachine;
  131. Array<llvm::DebugLoc> mSavedDebugLocs;
  132. llvm::InlineAsm* mNopInlineAsm;
  133. llvm::InlineAsm* mObjectCheckAsm;
  134. llvm::InlineAsm* mOverflowCheckAsm;
  135. llvm::DebugLoc mDebugLoc;
  136. BfCodeGenOptions mCodeGenOptions;
  137. bool mHasDebugLoc;
  138. bool mIsCodeView;
  139. bool mHadDLLExport;
  140. int mConstValIdx;
  141. int mCmdCount;
  142. int mCurLine;
  143. Dictionary<int, BfIRCodeGenEntry> mResults;
  144. Dictionary<int, BfIRTypeEntry> mTypes;
  145. Dictionary<int, llvm::Function*> mIntrinsicMap;
  146. Dictionary<BfTypeCode, BfIRTypeEx*> mTypeCodeTypeExMap;
  147. Dictionary<llvm::Type*, BfIRTypeEx*> mLLVMTypeExMap;
  148. Dictionary<BfIRTypeEx*, BfIRTypeEx*> mPointerTypeExMap;
  149. Dictionary<llvm::Function*, int> mIntrinsicReverseMap;
  150. Array<llvm::Constant*> mConfigConsts32;
  151. Array<llvm::Constant*> mConfigConsts64;
  152. Dictionary<BfIRTypeEx*, BfIRTypedValue> mReflectDataMap;
  153. Dictionary<BfIRTypeEx*, BfIRTypeEx*> mAlignedTypeToNormalType;
  154. Dictionary<BfIRTypeEx*, int> mTypeToTypeIdMap;
  155. HashSet<llvm::BasicBlock*> mLockedBlocks;
  156. OwnedArray<BfIRIntrinsicData> mIntrinsicData;
  157. Dictionary<llvm::Function*, BfIRSimdType> mFunctionsUsingSimd;
  158. Array<BfIRTypeEx*> mIRTypeExs;
  159. BfIRTypedValue mLastFuncCalled;
  160. public:
  161. void InitTarget();
  162. void FixValues(llvm::StructType* structType, llvm::SmallVector<llvm::Value*, 8>& values);
  163. void FixValues(llvm::StructType* structType, llvm::SmallVector<llvm::Constant*, 8>& values);
  164. void FixIndexer(llvm::Value*& val);
  165. void FixTypedValue(BfIRTypedValue& typedValue);
  166. BfTypeCode GetTypeCode(llvm::Type* type, bool isSigned);
  167. llvm::Type* GetLLVMType(BfTypeCode typeCode, bool& isSigned);
  168. BfIRTypeEx* GetTypeEx(llvm::Type* llvmType);
  169. BfIRTypeEx* CreateTypeEx(llvm::Type* llvmType);
  170. BfIRTypeEx* GetTypeEx(BfTypeCode typeCode, bool& isSigned);
  171. BfIRTypeEx* GetPointerTypeEx(BfIRTypeEx* typeEx);
  172. BfIRTypeEx* GetTypeMember(BfIRTypeEx* typeEx, int idx);
  173. BfIRTypeEntry& GetTypeEntry(int typeId);
  174. BfIRTypeEntry* GetTypeEntry(BfIRTypeEx* type);
  175. void SetResult(int id, llvm::Value* value);
  176. void SetResult(int id, const BfIRTypedValue& value);
  177. void SetResultAligned(int id, llvm::Value* value);
  178. void SetResultAligned(int id, const BfIRTypedValue& value);
  179. void SetResult(int id, llvm::Type* value);
  180. void SetResult(int id, BfIRTypeEx* typeEx);
  181. void SetResult(int id, llvm::BasicBlock* value);
  182. void SetResult(int id, llvm::MDNode* value);
  183. void CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile = false);
  184. void AddNop();
  185. llvm::Value* TryToVector(const BfIRTypedValue& value);
  186. bool TryMemCpy(const BfIRTypedValue& ptr, llvm::Value* val);
  187. bool TryVectorCpy(const BfIRTypedValue& ptr, llvm::Value* val);
  188. llvm::Type* GetLLVMPointerElementType(BfIRTypeEx* typeEx);
  189. BfIRTypeEx* GetSizeAlignedType(BfIRTypeEntry* typeEntry);
  190. BfIRTypedValue GetAlignedPtr(const BfIRTypedValue& val);
  191. llvm::Value* DoCheckedIntrinsic(llvm::Intrinsic::ID intrin, llvm::Value* lhs, llvm::Value* rhs, bool useAsm);
  192. void RunOptimizationPipeline(const llvm::Triple& targetTriple);
  193. public:
  194. BfIRCodeGen();
  195. ~BfIRCodeGen();
  196. void FatalError(const StringImpl& str);
  197. virtual void Fail(const StringImpl& error) override;
  198. void ProcessBfIRData(const BfSizedArray<uint8>& buffer) override;
  199. void PrintModule();
  200. void PrintFunction();
  201. int64 ReadSLEB128();
  202. void Read(StringImpl& str);
  203. void Read(int& i);
  204. void Read(int64& i);
  205. void Read(Val128& i);
  206. void Read(bool& val);
  207. void Read(int8& val);
  208. void Read(BfIRTypeEntry*& type);
  209. void Read(BfIRTypeEx*& typeEx, BfIRTypeEntry** outTypeEntry = NULL);
  210. void Read(llvm::Type*& llvmType, BfIRTypeEntry** outTypeEntry = NULL);
  211. void Read(llvm::FunctionType*& llvmType);
  212. void ReadFunctionType(BfIRTypeEx*& typeEx);
  213. void Read(BfIRTypedValue& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original);
  214. void Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original);
  215. void Read(llvm::Constant*& llvmConstant, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original);
  216. void Read(llvm::Function*& llvmFunc);
  217. void ReadFunction(BfIRTypedValue& typeEx);
  218. void Read(llvm::BasicBlock*& llvmBlock);
  219. void Read(llvm::MDNode*& llvmMD);
  220. void Read(llvm::Metadata*& llvmMD);
  221. template <typename T>
  222. void Read(llvm::SmallVectorImpl<T>& vec)
  223. {
  224. int len = (int)ReadSLEB128();
  225. for (int i = 0; i < len; i++)
  226. {
  227. T result;
  228. Read(result);
  229. vec.push_back(result);
  230. }
  231. }
  232. void Read(llvm::SmallVectorImpl<llvm::Value*>& vec, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original)
  233. {
  234. int len = (int)ReadSLEB128();
  235. for (int i = 0; i < len; i++)
  236. {
  237. llvm::Value* result;
  238. Read(result, NULL, sizeAlignKind);
  239. vec.push_back(result);
  240. }
  241. }
  242. void Read(llvm::SmallVectorImpl<llvm::Constant*>& vec, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original)
  243. {
  244. int len = (int)ReadSLEB128();
  245. for (int i = 0; i < len; i++)
  246. {
  247. llvm::Constant* result;
  248. Read(result, sizeAlignKind);
  249. vec.push_back(result);
  250. }
  251. }
  252. void HandleNextCmd() override;
  253. void SetCodeGenOptions(BfCodeGenOptions codeGenOptions);
  254. void SetConfigConst(int idx, int value) override;
  255. void SetActiveFunctionSimdType(BfIRSimdType type);
  256. String GetSimdTypeString(BfIRSimdType type);
  257. BfIRSimdType GetSimdTypeFromFunction(llvm::Function* function);
  258. BfIRTypedValue GetTypedValue(int streamId);
  259. llvm::Value* GetLLVMValue(int streamId);
  260. llvm::Type* GetLLVMType(int streamId);
  261. llvm::BasicBlock* GetLLVMBlock(int streamId);
  262. llvm::MDNode* GetLLVMMetadata(int streamId);
  263. llvm::Type* GetLLVMTypeById(int id);
  264. ///
  265. bool WriteObjectFile(const StringImpl& outFileName);
  266. bool WriteIR(const StringImpl& outFileName, StringImpl& error);
  267. void ApplySimdFeatures();
  268. static int GetIntrinsicId(const StringImpl& name);
  269. static const char* GetIntrinsicName(int intrinId);
  270. static void SetAsmKind(BfAsmKind asmKind);
  271. static void StaticInit();
  272. };
  273. NS_BF_END