Browse Source

Added memcpy opt for large arrays

Brian Fiete 5 năm trước cách đây
mục cha
commit
cf6d8a3a99

+ 0 - 5
IDEHelper/Compiler/BfIRBuilder.cpp

@@ -4428,11 +4428,6 @@ BfIRFunction BfIRBuilder::CreateFunction(BfIRFunctionType funcType, BfIRLinkageT
 	NEW_CMD_INSERTED_IRVALUE;	
 	NEW_CMD_INSERTED_IRVALUE;	
 	mFunctionMap[name] = retVal;
 	mFunctionMap[name] = retVal;
 
 
-	if (name == "?TestStructRetCapture$Rt@Lambdas@Tests@bf@@QEAA?AUStructA@123@XZ")
-	{
-		NOP;
-	}
-
 	//BfLogSys(mModule->mSystem, "BfIRBuilder::CreateFunction: %d %s Module:%p\n", retVal.mId, name.c_str(), mModule);
 	//BfLogSys(mModule->mSystem, "BfIRBuilder::CreateFunction: %d %s Module:%p\n", retVal.mId, name.c_str(), mModule);
 
 
 	return retVal;
 	return retVal;

+ 56 - 3
IDEHelper/Compiler/BfIRCodeGen.cpp

@@ -312,6 +312,7 @@ BfIRCodeGen::BfIRCodeGen()
 	mLLVMContext = new llvm::LLVMContext();
 	mLLVMContext = new llvm::LLVMContext();
 	mLLVMModule = NULL;
 	mLLVMModule = NULL;
 	mIsCodeView = false;
 	mIsCodeView = false;
+	mConstArrayIdx = 0;
 	mCmdCount = 0;
 	mCmdCount = 0;
 	
 	
 #ifdef BF_PLATFORM_WINDOWS
 #ifdef BF_PLATFORM_WINDOWS
@@ -961,6 +962,55 @@ void BfIRCodeGen::AddNop()
 	callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoUnwind);
 	callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoUnwind);
 }
 }
 
 
+bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val)
+{
+	auto arrayType = llvm::dyn_cast<llvm::ArrayType>(val->getType());
+	if (arrayType == NULL)
+		return false;
+	// LLVM has perf issues with large arrays - it treats each element as a unique value,
+	//  which is great for optimizing small data but is a perf killer for large data.
+	if (arrayType->getNumElements() <= 64)
+		return false;
+
+	auto int8Ty = llvm::Type::getInt8Ty(*mLLVMContext);
+	auto int8PtrTy = int8Ty->getPointerTo();
+	int arrayBytes = arrayType->getScalarSizeInBits() / 8;
+
+	if (auto loadInst = llvm::dyn_cast<llvm::LoadInst>(val))
+	{		
+		mIRBuilder->CreateMemCpy(
+			mIRBuilder->CreateBitCast(ptr, int8PtrTy),
+			1,
+			mIRBuilder->CreateBitCast(loadInst->getPointerOperand(), int8PtrTy),
+			1,
+			llvm::ConstantInt::get(int8Ty, arrayBytes));
+		return true;		
+	}
+
+	auto constVal = llvm::dyn_cast<llvm::Constant>(val);
+	if (constVal == NULL)
+		return false;					
+
+	auto globalVariable = new llvm::GlobalVariable(
+		*mLLVMModule,
+		arrayType,
+		true,
+		llvm::GlobalValue::InternalLinkage,
+		constVal,
+		StrFormat("__ConstArray__%d", mConstArrayIdx++).c_str(), 
+		NULL, 
+		llvm::GlobalValue::NotThreadLocal);
+	
+	mIRBuilder->CreateMemCpy(
+		mIRBuilder->CreateBitCast(ptr, int8PtrTy),
+		1,
+		mIRBuilder->CreateBitCast(globalVariable, int8PtrTy),
+		1,
+		llvm::ConstantInt::get(int8Ty, arrayBytes));
+
+	return true;
+}
+
 void BfIRCodeGen::CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile)
 void BfIRCodeGen::CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile)
 {
 {
 	auto sizeConst = llvm::dyn_cast<llvm::ConstantInt>(size);
 	auto sizeConst = llvm::dyn_cast<llvm::ConstantInt>(size);
@@ -1700,7 +1750,9 @@ void BfIRCodeGen::HandleNextCmd()
 			CMD_PARAM(llvm::Value*, val);
 			CMD_PARAM(llvm::Value*, val);
 			CMD_PARAM(llvm::Value*, ptr);
 			CMD_PARAM(llvm::Value*, ptr);
 			CMD_PARAM(bool, isVolatile);
 			CMD_PARAM(bool, isVolatile);
-			SetResult(curId, mIRBuilder->CreateStore(val, ptr, isVolatile));
+
+			if (!TryMemCpy(ptr, val))
+				SetResult(curId, mIRBuilder->CreateStore(val, ptr, isVolatile));
 		}
 		}
 		break;
 		break;
 	case BfIRCmd_AlignedStore:
 	case BfIRCmd_AlignedStore:
@@ -1709,7 +1761,8 @@ void BfIRCodeGen::HandleNextCmd()
 			CMD_PARAM(llvm::Value*, ptr);
 			CMD_PARAM(llvm::Value*, ptr);
 			CMD_PARAM(int, alignment);
 			CMD_PARAM(int, alignment);
 			CMD_PARAM(bool, isVolatile);
 			CMD_PARAM(bool, isVolatile);
-			SetResult(curId, mIRBuilder->CreateAlignedStore(val, ptr, alignment, isVolatile));
+			if (!TryMemCpy(ptr, val))
+				SetResult(curId, mIRBuilder->CreateAlignedStore(val, ptr, alignment, isVolatile));
 		}
 		}
 		break;
 		break;
 	case BfIRCmd_MemSet:
 	case BfIRCmd_MemSet:
@@ -1759,7 +1812,7 @@ void BfIRCodeGen::HandleNextCmd()
 				isConstant,
 				isConstant,
 				LLVMMapLinkageType(linkageType),
 				LLVMMapLinkageType(linkageType),
 				initializer,
 				initializer,
-				name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
+				name.c_str());
 			SetResult(curId, globalVariable);
 			SetResult(curId, globalVariable);
 		}
 		}
 		break;
 		break;

+ 3 - 1
IDEHelper/Compiler/BfIRCodeGen.h

@@ -76,7 +76,8 @@ public:
 	llvm::InlineAsm* mAsmObjectCheckAsm;	
 	llvm::InlineAsm* mAsmObjectCheckAsm;	
 	llvm::DebugLoc mDebugLoc;
 	llvm::DebugLoc mDebugLoc;
 	bool mHasDebugLoc;	
 	bool mHasDebugLoc;	
-	bool mIsCodeView;	
+	bool mIsCodeView;
+	int mConstArrayIdx;
 
 
 	int mCmdCount;
 	int mCmdCount;
 	Dictionary<int, BfIRCodeGenEntry> mResults;
 	Dictionary<int, BfIRCodeGenEntry> mResults;
@@ -96,6 +97,7 @@ public:
 	void SetResult(int id, llvm::MDNode* 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 CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile = false);
 	void AddNop();
 	void AddNop();
+	bool TryMemCpy(llvm::Value* ptr, llvm::Value* val);	
 
 
 public:
 public:
 	BfIRCodeGen();
 	BfIRCodeGen();