mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Start of SIMD support
This commit is contained in:
parent
73e260c1d5
commit
64b62c09be
30 changed files with 5846 additions and 5096 deletions
|
@ -134,6 +134,8 @@ struct BuiltinEntry
|
|||
static const BuiltinEntry gIntrinEntries[] =
|
||||
{
|
||||
{"abs"},
|
||||
{"add"},
|
||||
{"and"},
|
||||
{"atomic_add"},
|
||||
{"atomic_and"},
|
||||
{"atomic_cmpstore"},
|
||||
|
@ -153,21 +155,35 @@ static const BuiltinEntry gIntrinEntries[] =
|
|||
{"atomic_xor"},
|
||||
{"bswap"},
|
||||
{"cast"},
|
||||
{"cos"},
|
||||
{"cos"},
|
||||
{"div"},
|
||||
{"eq"},
|
||||
{"floor"},
|
||||
{"free"},
|
||||
{"gt"},
|
||||
{"gte"},
|
||||
{"log"},
|
||||
{"log10"},
|
||||
{"log2"},
|
||||
{"lt"},
|
||||
{"lte"},
|
||||
{"malloc"},
|
||||
{"memcpy"},
|
||||
{"memmove"},
|
||||
{"memset"},
|
||||
{"mod"},
|
||||
{"mul"},
|
||||
{"neq"},
|
||||
{"not"},
|
||||
{"or"},
|
||||
{"pow"},
|
||||
{"powi"},
|
||||
{"round"},
|
||||
{"shuffle"},
|
||||
{"sin"},
|
||||
{"sqrt"},
|
||||
{"sub"},
|
||||
{"xor"},
|
||||
};
|
||||
|
||||
#define CMD_PARAM(ty, name) ty name; Read(name);
|
||||
|
@ -1049,6 +1065,33 @@ void BfIRCodeGen::AddNop()
|
|||
callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoUnwind);
|
||||
}
|
||||
|
||||
llvm::Value* BfIRCodeGen::TryToVector(llvm::Value* value)
|
||||
{
|
||||
auto valueType = value->getType();
|
||||
if (llvm::isa<llvm::VectorType>(valueType))
|
||||
return value;
|
||||
|
||||
if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(valueType))
|
||||
{
|
||||
auto ptrElemType = ptrType->getElementType();
|
||||
if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(ptrElemType))
|
||||
{
|
||||
auto vecType = llvm::VectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements());
|
||||
auto vecPtrType = vecType->getPointerTo();
|
||||
|
||||
auto ptrVal0 = mIRBuilder->CreateBitCast(value, vecPtrType);
|
||||
return mIRBuilder->CreateAlignedLoad(ptrVal0, 1);
|
||||
}
|
||||
|
||||
if (auto vecType = llvm::dyn_cast<llvm::VectorType>(ptrElemType))
|
||||
{
|
||||
return mIRBuilder->CreateAlignedLoad(value, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val)
|
||||
{
|
||||
auto valType = val->getType();
|
||||
|
@ -1110,6 +1153,31 @@ bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BfIRCodeGen::TryVectorCpy(llvm::Value* ptr, llvm::Value* val)
|
||||
{
|
||||
if (ptr->getType()->getPointerElementType() == val->getType())
|
||||
return false;
|
||||
|
||||
auto valType = val->getType();
|
||||
auto vecType = llvm::dyn_cast<llvm::VectorType>(valType);
|
||||
if (vecType == NULL)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < (int)vecType->getVectorNumElements(); i++)
|
||||
{
|
||||
auto extract = mIRBuilder->CreateExtractElement(val, i);
|
||||
|
||||
llvm::Value* gepArgs[] = {
|
||||
llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0),
|
||||
llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), i) };
|
||||
auto gep = mIRBuilder->CreateInBoundsGEP(ptr, llvm::makeArrayRef(gepArgs));
|
||||
|
||||
mIRBuilder->CreateStore(extract, gep);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BfIRCodeGen::CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile)
|
||||
{
|
||||
auto sizeConst = llvm::dyn_cast<llvm::ConstantInt>(size);
|
||||
|
@ -1273,7 +1341,10 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
{
|
||||
CMD_PARAM(int, typeId);
|
||||
CMD_PARAM(llvm::Type*, type);
|
||||
GetTypeEntry(typeId).mLLVMType = type;
|
||||
auto& typeEntry = GetTypeEntry(typeId);
|
||||
typeEntry.mLLVMType = type;
|
||||
if (typeEntry.mInstLLVMType == NULL)
|
||||
typeEntry.mInstLLVMType = type;
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_SetInstType:
|
||||
|
@ -1359,6 +1430,13 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
SetResult(curId, llvm::ArrayType::get(elementType, length));
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_GetVectorType:
|
||||
{
|
||||
CMD_PARAM(llvm::Type*, elementType);
|
||||
CMD_PARAM(int, length);
|
||||
SetResult(curId, llvm::VectorType::get(elementType, length));
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_CreateConstStruct:
|
||||
{
|
||||
CMD_PARAM(llvm::Type*, type);
|
||||
|
@ -1854,8 +1932,9 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
CMD_PARAM(llvm::Value*, val);
|
||||
CMD_PARAM(llvm::Value*, ptr);
|
||||
CMD_PARAM(bool, isVolatile);
|
||||
|
||||
if (!TryMemCpy(ptr, val))
|
||||
|
||||
if ((!TryMemCpy(ptr, val)) &&
|
||||
(!TryVectorCpy(ptr, val)))
|
||||
SetResult(curId, mIRBuilder->CreateStore(val, ptr, isVolatile));
|
||||
}
|
||||
break;
|
||||
|
@ -1865,7 +1944,8 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
CMD_PARAM(llvm::Value*, ptr);
|
||||
CMD_PARAM(int, alignment);
|
||||
CMD_PARAM(bool, isVolatile);
|
||||
if (!TryMemCpy(ptr, val))
|
||||
if ((!TryMemCpy(ptr, val)) &&
|
||||
(!TryVectorCpy(ptr, val)))
|
||||
SetResult(curId, mIRBuilder->CreateAlignedStore(val, ptr, alignment, isVolatile));
|
||||
}
|
||||
break;
|
||||
|
@ -2116,29 +2196,11 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
break;
|
||||
case BfIRCmd_GetIntrinsic:
|
||||
{
|
||||
CMD_PARAM(String, intrinName);
|
||||
CMD_PARAM(int, intrinId);
|
||||
CMD_PARAM(llvm::Type*, returnType);
|
||||
CMD_PARAM(CmdParamVec<llvm::Type*>, paramTypes);
|
||||
|
||||
bool isFakeIntrinsic = false;
|
||||
if (((intrinId >= BfIRIntrinsic_Atomic_FIRST) && (intrinId <= BfIRIntrinsic_Atomic_LAST)) ||
|
||||
(intrinId == BfIRIntrinsic_Cast))
|
||||
{
|
||||
isFakeIntrinsic = true;
|
||||
}
|
||||
if (isFakeIntrinsic)
|
||||
{
|
||||
auto intrinsicData = mAlloc.Alloc<BfIRIntrinsicData>();
|
||||
intrinsicData->mIntrinsic = (BfIRIntrinsic)intrinId;
|
||||
intrinsicData->mReturnType = returnType;
|
||||
|
||||
BfIRCodeGenEntry entry;
|
||||
entry.mKind = BfIRCodeGenEntryKind_IntrinsicData;
|
||||
entry.mIntrinsicData = intrinsicData;
|
||||
mResults.TryAdd(curId, entry);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
llvm::Function* func = NULL;
|
||||
|
||||
struct _Intrinsics
|
||||
|
@ -2152,43 +2214,74 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
static _Intrinsics intrinsics[] =
|
||||
{
|
||||
{ llvm::Intrinsic::fabs, 0, -1},
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicAdd,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicAnd,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicCmpStore,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicCmpStore_Weak,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicCmpXChg,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicFence,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicLoad,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicMax,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicMin,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicNAnd,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicOr,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicStore,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicSub,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicUMax,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicUMin,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicXChg,
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicXor,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // add,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // and,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicAdd,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicAnd,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpStore,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpStore_Weak,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpXChg,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicFence,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicLoad,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicMax,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicMin,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicNAnd,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicOr,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicStore,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicSub,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicUMax,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicUMin,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicXChg,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // AtomicXor,
|
||||
{ llvm::Intrinsic::bswap, -1},
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // cast,
|
||||
{ llvm::Intrinsic::cos, 0, -1},
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // cast,
|
||||
{ llvm::Intrinsic::cos, 0, -1},
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // div
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // eq
|
||||
{ llvm::Intrinsic::floor, 0, -1},
|
||||
{ (llvm::Intrinsic::ID)-1, -1}, // free
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // free
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // gt
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // gte
|
||||
{ llvm::Intrinsic::log, 0, -1},
|
||||
{ llvm::Intrinsic::log10, 0, -1},
|
||||
{ llvm::Intrinsic::log2, 0, -1},
|
||||
{ (llvm::Intrinsic::ID)-1}, // memset
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // lt
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // lte
|
||||
{ (llvm::Intrinsic::ID)-2}, // memset
|
||||
{ llvm::Intrinsic::memcpy, 0, 1, 2},
|
||||
{ llvm::Intrinsic::memmove, 0, 2},
|
||||
{ llvm::Intrinsic::memset, 0, 2},
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // mod
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // mul
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // neq
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // not
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // or
|
||||
{ llvm::Intrinsic::pow, 0, -1},
|
||||
{ llvm::Intrinsic::powi, 0, -1},
|
||||
{ llvm::Intrinsic::round, 0, -1},
|
||||
{ llvm::Intrinsic::sin, 0, -1},
|
||||
{ llvm::Intrinsic::sqrt, 0, -1},
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // shuffle
|
||||
{ llvm::Intrinsic::sin, 0, -1},
|
||||
{ llvm::Intrinsic::sqrt, 0, -1},
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // sub,
|
||||
{ (llvm::Intrinsic::ID)-2, -1}, // xor
|
||||
};
|
||||
BF_STATIC_ASSERT(BF_ARRAY_COUNT(intrinsics) == BfIRIntrinsic_COUNT);
|
||||
|
||||
bool isFakeIntrinsic = (int)intrinsics[intrinId].mID == -2;
|
||||
if (isFakeIntrinsic)
|
||||
{
|
||||
auto intrinsicData = mAlloc.Alloc<BfIRIntrinsicData>();
|
||||
intrinsicData->mName = intrinName;
|
||||
intrinsicData->mIntrinsic = (BfIRIntrinsic)intrinId;
|
||||
intrinsicData->mReturnType = returnType;
|
||||
|
||||
BfIRCodeGenEntry entry;
|
||||
entry.mKind = BfIRCodeGenEntryKind_IntrinsicData;
|
||||
entry.mIntrinsicData = intrinsicData;
|
||||
mResults.TryAdd(curId, entry);
|
||||
break;
|
||||
}
|
||||
|
||||
CmdParamVec<llvm::Type*> useParams;
|
||||
if (intrinsics[intrinId].mArg0 != -1)
|
||||
{
|
||||
|
@ -2319,6 +2412,236 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
|
||||
switch (intrinsicData->mIntrinsic)
|
||||
{
|
||||
case BfIRIntrinsic_Add:
|
||||
case BfIRIntrinsic_And:
|
||||
case BfIRIntrinsic_Div:
|
||||
case BfIRIntrinsic_Eq:
|
||||
case BfIRIntrinsic_Gt:
|
||||
case BfIRIntrinsic_GtE:
|
||||
case BfIRIntrinsic_Lt:
|
||||
case BfIRIntrinsic_LtE:
|
||||
case BfIRIntrinsic_Mod:
|
||||
case BfIRIntrinsic_Mul:
|
||||
case BfIRIntrinsic_Neq:
|
||||
case BfIRIntrinsic_Or:
|
||||
case BfIRIntrinsic_Sub:
|
||||
case BfIRIntrinsic_Xor:
|
||||
{
|
||||
auto val0 = TryToVector(args[0]);
|
||||
if (val0 != NULL)
|
||||
{
|
||||
auto vecType = val0->getType();
|
||||
auto elemType = vecType->getVectorElementType();
|
||||
bool isFP = elemType->isFloatTy();
|
||||
|
||||
llvm::Value* val1;
|
||||
if (args.size() < 2)
|
||||
{
|
||||
llvm::Value* val;
|
||||
if (isFP)
|
||||
val = llvm::ConstantFP::get(elemType, 1);
|
||||
else
|
||||
val = llvm::ConstantInt::get(elemType, 1);
|
||||
val1 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), val, (uint64)0);
|
||||
val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)1);
|
||||
val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)2);
|
||||
val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)3);
|
||||
}
|
||||
else if (args[1]->getType()->isPointerTy())
|
||||
{
|
||||
auto ptrVal1 = mIRBuilder->CreateBitCast(args[1], vecType->getPointerTo());
|
||||
val1 = mIRBuilder->CreateAlignedLoad(ptrVal1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
val1 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), args[1], (uint64)0);
|
||||
val1 = mIRBuilder->CreateInsertElement(val1, args[1], (uint64)1);
|
||||
val1 = mIRBuilder->CreateInsertElement(val1, args[1], (uint64)2);
|
||||
val1 = mIRBuilder->CreateInsertElement(val1, args[1], (uint64)3);
|
||||
}
|
||||
|
||||
if (isFP)
|
||||
{
|
||||
llvm::Value* result = NULL;
|
||||
switch (intrinsicData->mIntrinsic)
|
||||
{
|
||||
case BfIRIntrinsic_Add:
|
||||
result = mIRBuilder->CreateFAdd(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Div:
|
||||
result = mIRBuilder->CreateFDiv(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Eq:
|
||||
result = mIRBuilder->CreateFCmpOEQ(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Gt:
|
||||
result = mIRBuilder->CreateFCmpOGT(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_GtE:
|
||||
result = mIRBuilder->CreateFCmpOGE(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Lt:
|
||||
result = mIRBuilder->CreateFCmpOLT(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_LtE:
|
||||
result = mIRBuilder->CreateFCmpOLE(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Mod:
|
||||
result = mIRBuilder->CreateFRem(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Mul:
|
||||
result = mIRBuilder->CreateFMul(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Neq:
|
||||
result = mIRBuilder->CreateFCmpONE(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Sub:
|
||||
result = mIRBuilder->CreateFSub(val0, val1);
|
||||
break;
|
||||
default:
|
||||
FatalError("Intrinsic argument error");
|
||||
}
|
||||
|
||||
if (result != NULL)
|
||||
{
|
||||
if (auto vecType = llvm::dyn_cast<llvm::VectorType>(result->getType()))
|
||||
{
|
||||
if (auto intType = llvm::dyn_cast<llvm::IntegerType>(vecType->getVectorElementType()))
|
||||
{
|
||||
if (intType->getBitWidth() == 1)
|
||||
{
|
||||
auto toType = llvm::VectorType::get(llvm::IntegerType::get(*mLLVMContext, 8), vecType->getVectorNumElements());
|
||||
result = mIRBuilder->CreateZExt(result, toType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetResult(curId, result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llvm::Value* result = NULL;
|
||||
switch (intrinsicData->mIntrinsic)
|
||||
{
|
||||
case BfIRIntrinsic_And:
|
||||
result = mIRBuilder->CreateAnd(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Add:
|
||||
result = mIRBuilder->CreateAdd(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Div:
|
||||
result = mIRBuilder->CreateSDiv(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Eq:
|
||||
result = mIRBuilder->CreateICmpEQ(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Gt:
|
||||
result = mIRBuilder->CreateICmpSGT(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_GtE:
|
||||
result = mIRBuilder->CreateICmpSGE(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Lt:
|
||||
result = mIRBuilder->CreateICmpSLT(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_LtE:
|
||||
result = mIRBuilder->CreateICmpSLE(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Mod:
|
||||
result = mIRBuilder->CreateSRem(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Mul:
|
||||
result = mIRBuilder->CreateMul(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Neq:
|
||||
result = mIRBuilder->CreateICmpNE(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Or:
|
||||
result = mIRBuilder->CreateOr(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Sub:
|
||||
result = mIRBuilder->CreateSub(val0, val1);
|
||||
break;
|
||||
case BfIRIntrinsic_Xor:
|
||||
result = mIRBuilder->CreateXor(val0, val1);
|
||||
break;
|
||||
default:
|
||||
FatalError("Intrinsic argument error");
|
||||
}
|
||||
|
||||
if (result != NULL)
|
||||
{
|
||||
if (auto vecType = llvm::dyn_cast<llvm::VectorType>(result->getType()))
|
||||
{
|
||||
if (auto intType = llvm::dyn_cast<llvm::IntegerType>(vecType->getVectorElementType()))
|
||||
{
|
||||
if (intType->getBitWidth() == 1)
|
||||
{
|
||||
auto toType = llvm::VectorType::get(llvm::IntegerType::get(*mLLVMContext, 8), vecType->getVectorNumElements());
|
||||
result = mIRBuilder->CreateZExt(result, toType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetResult(curId, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(args[1]->getType()))
|
||||
{
|
||||
auto ptrElemType = ptrType->getElementType();
|
||||
if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(ptrElemType))
|
||||
{
|
||||
auto vecType = llvm::VectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements());
|
||||
auto vecPtrType = vecType->getPointerTo();
|
||||
|
||||
llvm::Value* val0;
|
||||
val0 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), args[0], (uint64)0);
|
||||
val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)1);
|
||||
val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)2);
|
||||
val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)3);
|
||||
|
||||
auto ptrVal1 = mIRBuilder->CreateBitCast(args[1], vecPtrType);
|
||||
auto val1 = mIRBuilder->CreateAlignedLoad(ptrVal1, 1);
|
||||
|
||||
switch (intrinsicData->mIntrinsic)
|
||||
{
|
||||
case BfIRIntrinsic_Div:
|
||||
SetResult(curId, mIRBuilder->CreateFDiv(val0, val1));
|
||||
break;
|
||||
case BfIRIntrinsic_Mod:
|
||||
SetResult(curId, mIRBuilder->CreateFRem(val0, val1));
|
||||
break;
|
||||
default:
|
||||
FatalError("Intrinsic argument error");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalError("Intrinsic argument error");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BfIRIntrinsic_Shuffle:
|
||||
{
|
||||
llvm::SmallVector<uint, 8> intMask;
|
||||
for (int i = 7; i < (int)intrinsicData->mName.length(); i++)
|
||||
intMask.push_back((uint)(intrinsicData->mName[i] - '0'));
|
||||
|
||||
auto val0 = TryToVector(args[0]);
|
||||
|
||||
if (val0 != NULL)
|
||||
{
|
||||
SetResult(curId, mIRBuilder->CreateShuffleVector(val0, val0, intMask));
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalError("Intrinsic argument error");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BfIRIntrinsic_AtomicCmpStore:
|
||||
case BfIRIntrinsic_AtomicCmpStore_Weak:
|
||||
case BfIRIntrinsic_AtomicCmpXChg:
|
||||
|
@ -2326,7 +2649,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[3]);
|
||||
if (memoryKindConst == NULL)
|
||||
{
|
||||
Fail("Non-constant success ordering on Atomic_CmpXChg");
|
||||
FatalError("Non-constant success ordering on Atomic_CmpXChg");
|
||||
break;
|
||||
}
|
||||
auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
|
||||
|
@ -2365,7 +2688,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[4]);
|
||||
if (memoryKindConst == NULL)
|
||||
{
|
||||
Fail("Non-constant fail ordering on Atomic_CmpXChg");
|
||||
FatalError("Non-constant fail ordering on Atomic_CmpXChg");
|
||||
break;
|
||||
}
|
||||
auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
|
||||
|
@ -2381,7 +2704,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
failOrdering = llvm::AtomicOrdering::SequentiallyConsistent;
|
||||
break;
|
||||
default:
|
||||
Fail("Invalid fail ordering on Atomic_CmpXChg");
|
||||
FatalError("Invalid fail ordering on Atomic_CmpXChg");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2427,7 +2750,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[0]);
|
||||
if (memoryKindConst == NULL)
|
||||
{
|
||||
Fail("Non-constant success ordering on AtomicFence");
|
||||
FatalError("Non-constant success ordering on AtomicFence");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2460,7 +2783,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[1]);
|
||||
if (memoryKindConst == NULL)
|
||||
{
|
||||
Fail("Non-constant success ordering on AtomicLoad");
|
||||
FatalError("Non-constant success ordering on AtomicLoad");
|
||||
break;
|
||||
}
|
||||
auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
|
||||
|
@ -2490,7 +2813,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[1]);
|
||||
if (memoryKindConst == NULL)
|
||||
{
|
||||
Fail("Non-constant success ordering on AtomicLoad");
|
||||
FatalError("Non-constant success ordering on AtomicLoad");
|
||||
break;
|
||||
}
|
||||
auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
|
||||
|
@ -2569,7 +2892,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[2]);
|
||||
if (memoryKindConst == NULL)
|
||||
{
|
||||
Fail("Non-constant ordering on atomic operation");
|
||||
FatalError("Non-constant ordering on atomic operation");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2676,7 +2999,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
}
|
||||
break;
|
||||
default:
|
||||
Fail("Unhandled intrinsic");
|
||||
FatalError("Unhandled intrinsic");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3115,7 +3438,10 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
{
|
||||
CMD_PARAM(int, typeId);
|
||||
CMD_PARAM(llvm::MDNode*, type);
|
||||
GetTypeEntry(typeId).mDIType = (llvm::DIType*)type;
|
||||
auto& typeEntry = GetTypeEntry(typeId);
|
||||
typeEntry.mDIType = (llvm::DIType*)type;
|
||||
if (typeEntry.mInstDIType == NULL)
|
||||
typeEntry.mInstDIType = (llvm::DIType*)type;
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_DbgSetInstType:
|
||||
|
@ -4537,17 +4863,16 @@ bool BfIRCodeGen::WriteIR(const StringImpl& outFileName, StringImpl& error)
|
|||
}
|
||||
|
||||
int BfIRCodeGen::GetIntrinsicId(const StringImpl& name)
|
||||
{
|
||||
// llvm::Intrinsic::ID intrin = llvm::Intrinsic::getIntrinsicForGCCBuiltin("x86", name.c_str());
|
||||
// if (intrin != llvm::Intrinsic::not_intrinsic)
|
||||
// return (int)intrin;
|
||||
|
||||
{
|
||||
auto itr = std::lower_bound(std::begin(gIntrinEntries), std::end(gIntrinEntries), name);
|
||||
if (itr != std::end(gIntrinEntries) && strcmp(itr->mName, name.c_str()) == 0)
|
||||
{
|
||||
int id = (int)(itr - gIntrinEntries);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
if (name.StartsWith("shuffle"))
|
||||
return BfIRIntrinsic_Shuffle;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue