1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Extended TryMemCpy to work on structs

This commit is contained in:
Brian Fiete 2020-08-12 11:42:15 -07:00
parent 0adfbce884
commit 0fbe15040d
2 changed files with 24 additions and 15 deletions

View file

@ -312,7 +312,7 @@ BfIRCodeGen::BfIRCodeGen()
mLLVMContext = new llvm::LLVMContext(); mLLVMContext = new llvm::LLVMContext();
mLLVMModule = NULL; mLLVMModule = NULL;
mIsCodeView = false; mIsCodeView = false;
mConstArrayIdx = 0; mConstValIdx = 0;
mCmdCount = 0; mCmdCount = 0;
#ifdef BF_PLATFORM_WINDOWS #ifdef BF_PLATFORM_WINDOWS
@ -1050,21 +1050,20 @@ void BfIRCodeGen::AddNop()
} }
bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val) bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val)
{ {
auto arrayType = llvm::dyn_cast<llvm::ArrayType>(val->getType()); auto valType = val->getType();
if (arrayType == NULL)
return false; auto dataLayout = llvm::DataLayout(mLLVMModule);
// LLVM has perf issues with large arrays - it treats each element as a unique value, int arrayBytes = (int)dataLayout.getTypeSizeInBits(valType) / 8;
// LLVM has perf issues with large aggregates - it treats each element as a unique value,
// which is great for optimizing small data but is a perf killer for large data. // which is great for optimizing small data but is a perf killer for large data.
if (arrayType->getNumElements() <= 64) if (arrayBytes < 256)
return false; return false;
auto int8Ty = llvm::Type::getInt8Ty(*mLLVMContext); auto int8Ty = llvm::Type::getInt8Ty(*mLLVMContext);
auto int32Ty = llvm::Type::getInt32Ty(*mLLVMContext); auto int32Ty = llvm::Type::getInt32Ty(*mLLVMContext);
auto int8PtrTy = int8Ty->getPointerTo(); auto int8PtrTy = int8Ty->getPointerTo();
auto dataLayout = llvm::DataLayout(mLLVMModule);
int arrayBytes = (int)dataLayout.getTypeSizeInBits(arrayType) / 8;
if (auto loadInst = llvm::dyn_cast<llvm::LoadInst>(val)) if (auto loadInst = llvm::dyn_cast<llvm::LoadInst>(val))
{ {
@ -1079,15 +1078,25 @@ bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val)
auto constVal = llvm::dyn_cast<llvm::Constant>(val); auto constVal = llvm::dyn_cast<llvm::Constant>(val);
if (constVal == NULL) if (constVal == NULL)
return false; return false;
if (llvm::isa<llvm::ConstantAggregateZero>(constVal))
{
mIRBuilder->CreateMemSet(
mIRBuilder->CreateBitCast(ptr, int8PtrTy),
llvm::ConstantInt::get(int8Ty, 0),
llvm::ConstantInt::get(int32Ty, arrayBytes),
1);
return true;
}
auto globalVariable = new llvm::GlobalVariable( auto globalVariable = new llvm::GlobalVariable(
*mLLVMModule, *mLLVMModule,
arrayType, valType,
true, true,
llvm::GlobalValue::InternalLinkage, llvm::GlobalValue::InternalLinkage,
constVal, constVal,
StrFormat("__ConstArray__%d", mConstArrayIdx++).c_str(), StrFormat("__ConstVal__%d", mConstValIdx++).c_str(),
NULL, NULL,
llvm::GlobalValue::NotThreadLocal); llvm::GlobalValue::NotThreadLocal);

View file

@ -77,7 +77,7 @@ public:
llvm::DebugLoc mDebugLoc; llvm::DebugLoc mDebugLoc;
bool mHasDebugLoc; bool mHasDebugLoc;
bool mIsCodeView; bool mIsCodeView;
int mConstArrayIdx; int mConstValIdx;
int mCmdCount; int mCmdCount;
Dictionary<int, BfIRCodeGenEntry> mResults; Dictionary<int, BfIRCodeGenEntry> mResults;