mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 20:42:21 +02:00
Arithmetic overflow checks
This commit is contained in:
parent
1f0d2dcc82
commit
eb375362a1
29 changed files with 503 additions and 87 deletions
|
@ -9729,7 +9729,8 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje
|
|||
// }
|
||||
BF_ASSERT(!options->mEnableRealtimeLeakCheck);
|
||||
#endif
|
||||
options->mEmitObjectAccessCheck = (optionFlags & BfCompilerOptionFlag_EmitDebugInfo) != 0;
|
||||
options->mEmitObjectAccessCheck = (optionFlags & BfCompilerOptionFlag_EmitObjectAccessCheck) != 0;
|
||||
options->mArithmeticChecks = (optionFlags & BfCompilerOptionFlag_ArithmeticChecks) != 0;
|
||||
options->mAllocStackCount = allocStackCount;
|
||||
|
||||
if (hotProject != NULL)
|
||||
|
@ -9770,6 +9771,7 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje
|
|||
options->mObjectHasDebugFlags = false;
|
||||
options->mEnableRealtimeLeakCheck = false;
|
||||
options->mEmitObjectAccessCheck = false;
|
||||
options->mArithmeticChecks = false;
|
||||
options->mEmitDynamicCastCheck = false;
|
||||
options->mRuntimeChecks = (optionFlags & BfCompilerOptionFlag_RuntimeChecks) != 0;
|
||||
}
|
||||
|
|
|
@ -117,7 +117,8 @@ public:
|
|||
bool mAllowHotSwapping;
|
||||
bool mObjectHasDebugFlags;
|
||||
bool mEnableRealtimeLeakCheck;
|
||||
bool mEmitObjectAccessCheck; // Only valid with mObjectHasDebugFlags
|
||||
bool mEmitObjectAccessCheck; // Only valid with mObjectHasDebugFlags
|
||||
bool mArithmeticChecks;
|
||||
bool mEnableCustodian;
|
||||
bool mEnableSideStack;
|
||||
bool mHasVDataExtender;
|
||||
|
@ -162,6 +163,7 @@ public:
|
|||
mEmitDynamicCastCheck = true;
|
||||
mAllowHotSwapping = false;
|
||||
mEmitObjectAccessCheck = false;
|
||||
mArithmeticChecks = false;
|
||||
mObjectHasDebugFlags = false;
|
||||
mEnableRealtimeLeakCheck = false;
|
||||
mWriteIR = false;
|
||||
|
|
|
@ -2200,6 +2200,7 @@ void BfContext::UpdateRevisedTypes()
|
|||
workspaceConfigHashCtx.Mixin(options->mObjectHasDebugFlags);
|
||||
workspaceConfigHashCtx.Mixin(options->mEnableRealtimeLeakCheck);
|
||||
workspaceConfigHashCtx.Mixin(options->mEmitObjectAccessCheck);
|
||||
workspaceConfigHashCtx.Mixin(options->mArithmeticChecks);
|
||||
workspaceConfigHashCtx.Mixin(options->mEnableCustodian);
|
||||
workspaceConfigHashCtx.Mixin(options->mEnableSideStack);
|
||||
workspaceConfigHashCtx.Mixin(options->mHasVDataExtender);
|
||||
|
|
|
@ -19769,7 +19769,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
|||
|
||||
bool wantsChecks = checkedKind == BfCheckedKind_Checked;
|
||||
if (checkedKind == BfCheckedKind_NotSet)
|
||||
wantsChecks = mModule->GetDefaultCheckedKind() == BfCheckedKind_Checked;
|
||||
wantsChecks = mModule->GetDefaultCheckedKind() == BfCheckedKind_Checked;
|
||||
|
||||
//target.mType = mModule->ResolveGenericType(target.mType);
|
||||
if (target.mType->IsVar())
|
||||
|
@ -22665,23 +22665,43 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
|||
return;
|
||||
}
|
||||
|
||||
auto _GetOverflowKind = [&](bool wantOverflow)
|
||||
{
|
||||
if (!wantOverflow)
|
||||
return BfOverflowCheckKind_None;
|
||||
if (mModule->GetDefaultCheckedKind() != BfCheckedKind_Checked)
|
||||
return BfOverflowCheckKind_None;
|
||||
|
||||
bool arithmeticChecks = mModule->mCompiler->mOptions.mArithmeticChecks;
|
||||
auto typeOptions = mModule->GetTypeOptions();
|
||||
if (typeOptions != NULL)
|
||||
arithmeticChecks = typeOptions->Apply(arithmeticChecks, BfOptionFlags_ArithmeticCheck);
|
||||
if (!arithmeticChecks)
|
||||
return BfOverflowCheckKind_None;
|
||||
|
||||
BfOverflowCheckKind overflowCheckKind = (resultType->IsSigned()) ? BfOverflowCheckKind_Signed : BfOverflowCheckKind_Unsigned;
|
||||
if (!mModule->IsOptimized())
|
||||
overflowCheckKind = (BfOverflowCheckKind)(overflowCheckKind | BfOverflowCheckKind_Flag_UseAsm);
|
||||
return overflowCheckKind;
|
||||
};
|
||||
|
||||
switch (binaryOp)
|
||||
{
|
||||
case BfBinaryOp_Add:
|
||||
case BfBinaryOp_OverflowAdd:
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAdd(convLeftValue, convRightValue), resultType);
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAdd(convLeftValue, convRightValue, _GetOverflowKind(binaryOp == BfBinaryOp_Add)), resultType);
|
||||
if (binaryOp != BfBinaryOp_OverflowAdd)
|
||||
mModule->CheckRangeError(resultType, opToken);
|
||||
break;
|
||||
case BfBinaryOp_Subtract:
|
||||
case BfBinaryOp_OverflowSubtract:
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue), resultType);
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue, _GetOverflowKind(binaryOp == BfBinaryOp_Subtract)), resultType);
|
||||
if (binaryOp != BfBinaryOp_OverflowSubtract)
|
||||
mModule->CheckRangeError(resultType, opToken);
|
||||
break;
|
||||
case BfBinaryOp_Multiply:
|
||||
case BfBinaryOp_OverflowMultiply:
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateMul(convLeftValue, convRightValue), resultType);
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateMul(convLeftValue, convRightValue, _GetOverflowKind(binaryOp == BfBinaryOp_Multiply)), resultType);
|
||||
if (binaryOp != BfBinaryOp_OverflowMultiply)
|
||||
mModule->CheckRangeError(resultType, opToken);
|
||||
break;
|
||||
|
|
|
@ -4248,7 +4248,7 @@ BfIRValue BfIRBuilder::CreateCmpGTE(BfIRValue lhs, BfIRValue rhs, bool isSigned)
|
|||
return retVal;
|
||||
}
|
||||
|
||||
BfIRValue BfIRBuilder::CreateAdd(BfIRValue lhs, BfIRValue rhs)
|
||||
BfIRValue BfIRBuilder::CreateAdd(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind)
|
||||
{
|
||||
mOpFailed = false;
|
||||
if ((lhs.IsConst()) && (rhs.IsConst()))
|
||||
|
@ -4260,12 +4260,19 @@ BfIRValue BfIRBuilder::CreateAdd(BfIRValue lhs, BfIRValue rhs)
|
|||
}
|
||||
}
|
||||
|
||||
auto retVal = WriteCmd(BfIRCmd_Add, lhs, rhs);
|
||||
auto retVal = WriteCmd(BfIRCmd_Add, lhs, rhs, overflowCheckKind);
|
||||
NEW_CMD_INSERTED_IRVALUE;
|
||||
|
||||
if ((overflowCheckKind != BfOverflowCheckKind_None) && (!mIgnoreWrites))
|
||||
{
|
||||
mInsertBlock = mActualInsertBlock = WriteCmd(BfIRCmd_GetInsertBlock);
|
||||
NEW_CMD_INSERTED_IRVALUE;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
BfIRValue BfIRBuilder::CreateSub(BfIRValue lhs, BfIRValue rhs)
|
||||
BfIRValue BfIRBuilder::CreateSub(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind)
|
||||
{
|
||||
mOpFailed = false;
|
||||
if ((lhs.IsConst()) && (rhs.IsConst()))
|
||||
|
@ -4273,12 +4280,19 @@ BfIRValue BfIRBuilder::CreateSub(BfIRValue lhs, BfIRValue rhs)
|
|||
BINOPFUNC_APPLY(lhs, rhs, CheckedSub);
|
||||
}
|
||||
|
||||
auto retVal = WriteCmd(BfIRCmd_Sub, lhs, rhs);
|
||||
auto retVal = WriteCmd(BfIRCmd_Sub, lhs, rhs, overflowCheckKind);
|
||||
NEW_CMD_INSERTED;
|
||||
|
||||
if ((overflowCheckKind != BfOverflowCheckKind_None) && (!mIgnoreWrites))
|
||||
{
|
||||
mInsertBlock = mActualInsertBlock = WriteCmd(BfIRCmd_GetInsertBlock);
|
||||
NEW_CMD_INSERTED_IRVALUE;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
BfIRValue BfIRBuilder::CreateMul(BfIRValue lhs, BfIRValue rhs)
|
||||
BfIRValue BfIRBuilder::CreateMul(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind)
|
||||
{
|
||||
mOpFailed = false;
|
||||
if ((lhs.IsConst()) && (rhs.IsConst()))
|
||||
|
@ -4286,8 +4300,15 @@ BfIRValue BfIRBuilder::CreateMul(BfIRValue lhs, BfIRValue rhs)
|
|||
BINOPFUNC_APPLY(lhs, rhs, CheckedMul);
|
||||
}
|
||||
|
||||
auto retVal = WriteCmd(BfIRCmd_Mul, lhs, rhs);
|
||||
auto retVal = WriteCmd(BfIRCmd_Mul, lhs, rhs, overflowCheckKind);
|
||||
NEW_CMD_INSERTED_IRVALUE;
|
||||
|
||||
if ((overflowCheckKind != BfOverflowCheckKind_None) && (!mIgnoreWrites))
|
||||
{
|
||||
mInsertBlock = mActualInsertBlock = WriteCmd(BfIRCmd_GetInsertBlock);
|
||||
NEW_CMD_INSERTED_IRVALUE;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -5394,7 +5415,7 @@ void BfIRBuilder::CreateStatementStart()
|
|||
}
|
||||
|
||||
void BfIRBuilder::CreateObjectAccessCheck(BfIRValue value, bool useAsm)
|
||||
{
|
||||
{
|
||||
auto retBlock = WriteCmd(BfIRCmd_ObjectAccessCheck, value, useAsm);
|
||||
NEW_CMD_INSERTED_IRBLOCK;
|
||||
if (!mIgnoreWrites)
|
||||
|
|
|
@ -174,7 +174,7 @@ enum BfIRCmd : uint8
|
|||
|
||||
BfIRCmd_SetName,
|
||||
BfIRCmd_CreateUndefValue,
|
||||
BfIRCmd_NumericCast,
|
||||
BfIRCmd_NumericCast,
|
||||
BfIRCmd_CmpEQ,
|
||||
BfIRCmd_CmpNE,
|
||||
BfIRCmd_CmpSLT,
|
||||
|
@ -247,6 +247,7 @@ enum BfIRCmd : uint8
|
|||
BfIRCmd_AddBlock,
|
||||
BfIRCmd_DropBlocks,
|
||||
BfIRCmd_MergeBlockDown,
|
||||
BfIRCmd_GetInsertBlock,
|
||||
BfIRCmd_SetInsertPoint,
|
||||
BfIRCmd_SetInsertPointAtStart,
|
||||
BfIRCmd_EraseFromParent,
|
||||
|
@ -964,6 +965,14 @@ struct BfIRState
|
|||
Array<BfFilePosition> mSavedDebugLocs;
|
||||
};
|
||||
|
||||
enum BfOverflowCheckKind : int8
|
||||
{
|
||||
BfOverflowCheckKind_None = 0,
|
||||
BfOverflowCheckKind_Signed = 1,
|
||||
BfOverflowCheckKind_Unsigned = 2,
|
||||
BfOverflowCheckKind_Flag_UseAsm = 4
|
||||
};
|
||||
|
||||
class BfIRBuilder : public BfIRConstHolder
|
||||
{
|
||||
public:
|
||||
|
@ -1182,9 +1191,9 @@ public:
|
|||
BfIRValue CreateCmpLTE(BfIRValue lhs, BfIRValue rhs, bool isSigned);
|
||||
BfIRValue CreateCmpGT(BfIRValue lhs, BfIRValue rhs, bool isSigned);
|
||||
BfIRValue CreateCmpGTE(BfIRValue lhs, BfIRValue rhs, bool isSigned);
|
||||
BfIRValue CreateAdd(BfIRValue lhs, BfIRValue rhs);
|
||||
BfIRValue CreateSub(BfIRValue lhs, BfIRValue rhs);
|
||||
BfIRValue CreateMul(BfIRValue lhs, BfIRValue rhs);
|
||||
BfIRValue CreateAdd(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind = BfOverflowCheckKind_None);
|
||||
BfIRValue CreateSub(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind = BfOverflowCheckKind_None);
|
||||
BfIRValue CreateMul(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind = BfOverflowCheckKind_None);
|
||||
BfIRValue CreateDiv(BfIRValue lhs, BfIRValue rhs, bool isSigned);
|
||||
BfIRValue CreateRem(BfIRValue lhs, BfIRValue rhs, bool isSigned);
|
||||
BfIRValue CreateAnd(BfIRValue lhs, BfIRValue rhs);
|
||||
|
|
|
@ -340,7 +340,8 @@ BfIRCodeGen::BfIRCodeGen()
|
|||
mLLVMTargetMachine = NULL;
|
||||
|
||||
mNopInlineAsm = NULL;
|
||||
mAsmObjectCheckAsm = NULL;
|
||||
mObjectCheckAsm = NULL;
|
||||
mOverflowCheckAsm = NULL;
|
||||
mHasDebugLoc = false;
|
||||
mAttrSet = NULL;
|
||||
mIRBuilder = NULL;
|
||||
|
@ -730,6 +731,11 @@ void BfIRCodeGen::Read(bool& val)
|
|||
val = mStream->Read() != 0;
|
||||
}
|
||||
|
||||
void BfIRCodeGen::Read(int8& val)
|
||||
{
|
||||
val = mStream->Read();
|
||||
}
|
||||
|
||||
void BfIRCodeGen::Read(BfIRTypeEntry*& type)
|
||||
{
|
||||
int typeId = (int)ReadSLEB128();
|
||||
|
@ -1447,6 +1453,72 @@ llvm::Value* BfIRCodeGen::FixGEP(llvm::Value* fromValue, llvm::Value* result)
|
|||
return result;
|
||||
}
|
||||
|
||||
llvm::Value* BfIRCodeGen::DoCheckedIntrinsic(llvm::Intrinsic::ID intrin, llvm::Value* lhs, llvm::Value* rhs, bool useAsm)
|
||||
{
|
||||
if ((mTargetTriple.GetMachineType() != BfMachineType_x86) && (mTargetTriple.GetMachineType() != BfMachineType_x64))
|
||||
useAsm = false;
|
||||
|
||||
CmdParamVec<llvm::Type*> useParams;
|
||||
useParams.push_back(lhs->getType());
|
||||
auto func = llvm::Intrinsic::getDeclaration(mLLVMModule, intrin, useParams);
|
||||
|
||||
CmdParamVec<llvm::Value*> args;
|
||||
args.push_back(lhs);
|
||||
args.push_back(rhs);
|
||||
llvm::FunctionType* funcType = NULL;
|
||||
if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(func->getType()))
|
||||
funcType = llvm::dyn_cast<llvm::FunctionType>(ptrType->getElementType());
|
||||
auto aggResult = mIRBuilder->CreateCall(funcType, func, args);
|
||||
auto valResult = mIRBuilder->CreateExtractValue(aggResult, 0);
|
||||
auto failResult = mIRBuilder->CreateExtractValue(aggResult, 1);
|
||||
|
||||
if (!useAsm)
|
||||
{
|
||||
mLockedBlocks.Add(mIRBuilder->GetInsertBlock());
|
||||
|
||||
auto failBB = llvm::BasicBlock::Create(*mLLVMContext, "access.fail");
|
||||
auto passBB = llvm::BasicBlock::Create(*mLLVMContext, "access.pass");
|
||||
|
||||
mIRBuilder->CreateCondBr(failResult, failBB, passBB);
|
||||
|
||||
mActiveFunction->getBasicBlockList().push_back(failBB);
|
||||
mIRBuilder->SetInsertPoint(failBB);
|
||||
|
||||
auto trapDecl = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::trap);
|
||||
auto callInst = mIRBuilder->CreateCall(trapDecl);
|
||||
callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoReturn);
|
||||
mIRBuilder->CreateBr(passBB);
|
||||
|
||||
mActiveFunction->getBasicBlockList().push_back(passBB);
|
||||
mIRBuilder->SetInsertPoint(passBB);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mOverflowCheckAsm == NULL)
|
||||
{
|
||||
std::vector<llvm::Type*> paramTypes;
|
||||
paramTypes.push_back(llvm::Type::getInt8Ty(*mLLVMContext));
|
||||
auto funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*mLLVMContext), paramTypes, false);
|
||||
|
||||
String asmStr =
|
||||
"testb $$1, $0\n"
|
||||
"jz 1f\n"
|
||||
"int $$3\n"
|
||||
"1:";
|
||||
|
||||
mOverflowCheckAsm = llvm::InlineAsm::get(funcType,
|
||||
asmStr.c_str(), "r,~{dirflag},~{fpsr},~{flags}", true,
|
||||
false, llvm::InlineAsm::AD_ATT);
|
||||
}
|
||||
|
||||
llvm::SmallVector<llvm::Value*, 1> llvmArgs;
|
||||
llvmArgs.push_back(mIRBuilder->CreateIntCast(failResult, llvm::Type::getInt8Ty(*mLLVMContext), false));
|
||||
llvm::CallInst* callInst = mIRBuilder->CreateCall(mOverflowCheckAsm, llvmArgs);
|
||||
callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoUnwind);
|
||||
}
|
||||
return valResult;
|
||||
}
|
||||
|
||||
void BfIRCodeGen::CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile)
|
||||
{
|
||||
auto sizeConst = llvm::dyn_cast<llvm::ConstantInt>(size);
|
||||
|
@ -2040,22 +2112,31 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
SetResult(curId, mIRBuilder->CreateICmpUGE(lhs, rhs));
|
||||
}
|
||||
break;
|
||||
|
||||
case BfIRCmd_Add:
|
||||
{
|
||||
CMD_PARAM(llvm::Value*, lhs);
|
||||
CMD_PARAM(llvm::Value*, rhs);
|
||||
CMD_PARAM(int8, overflowCheckKind);
|
||||
if (lhs->getType()->isFloatingPointTy())
|
||||
SetResult(curId, mIRBuilder->CreateFAdd(lhs, rhs));
|
||||
else if ((overflowCheckKind & (BfOverflowCheckKind_Signed | BfOverflowCheckKind_Unsigned)) != 0)
|
||||
SetResult(curId, DoCheckedIntrinsic(((overflowCheckKind & BfOverflowCheckKind_Signed) != 0) ? llvm::Intrinsic::sadd_with_overflow : llvm::Intrinsic::uadd_with_overflow,
|
||||
lhs, rhs, (overflowCheckKind & BfOverflowCheckKind_Flag_UseAsm) != 0));
|
||||
else
|
||||
SetResult(curId, mIRBuilder->CreateAdd(lhs, rhs));
|
||||
SetResult(curId, mIRBuilder->CreateAdd(lhs, rhs));
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_Sub:
|
||||
{
|
||||
CMD_PARAM(llvm::Value*, lhs);
|
||||
CMD_PARAM(llvm::Value*, rhs);
|
||||
CMD_PARAM(int8, overflowCheckKind);
|
||||
if (lhs->getType()->isFloatingPointTy())
|
||||
SetResult(curId, mIRBuilder->CreateFSub(lhs, rhs));
|
||||
else if ((overflowCheckKind & (BfOverflowCheckKind_Signed | BfOverflowCheckKind_Unsigned)) != 0)
|
||||
SetResult(curId, DoCheckedIntrinsic(((overflowCheckKind & BfOverflowCheckKind_Signed) != 0) ? llvm::Intrinsic::ssub_with_overflow : llvm::Intrinsic::usub_with_overflow,
|
||||
lhs, rhs, (overflowCheckKind & BfOverflowCheckKind_Flag_UseAsm) != 0));
|
||||
else
|
||||
SetResult(curId, mIRBuilder->CreateSub(lhs, rhs));
|
||||
}
|
||||
|
@ -2064,8 +2145,12 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
{
|
||||
CMD_PARAM(llvm::Value*, lhs);
|
||||
CMD_PARAM(llvm::Value*, rhs);
|
||||
CMD_PARAM(int8, overflowCheckKind);
|
||||
if (lhs->getType()->isFloatingPointTy())
|
||||
SetResult(curId, mIRBuilder->CreateFMul(lhs, rhs));
|
||||
else if ((overflowCheckKind & (BfOverflowCheckKind_Signed | BfOverflowCheckKind_Unsigned)) != 0)
|
||||
SetResult(curId, DoCheckedIntrinsic(((overflowCheckKind & BfOverflowCheckKind_Signed) != 0) ? llvm::Intrinsic::smul_with_overflow : llvm::Intrinsic::umul_with_overflow,
|
||||
lhs, rhs, (overflowCheckKind & BfOverflowCheckKind_Flag_UseAsm) != 0));
|
||||
else
|
||||
SetResult(curId, mIRBuilder->CreateMul(lhs, rhs));
|
||||
}
|
||||
|
@ -2528,7 +2613,12 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
intoInstList.splice(intoInstList.begin(), fromInstList, fromInstList.begin(), fromInstList.end());
|
||||
fromBlock->eraseFromParent();
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case BfIRCmd_GetInsertBlock:
|
||||
{
|
||||
SetResult(curId, mIRBuilder->GetInsertBlock());
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_SetInsertPoint:
|
||||
{
|
||||
CMD_PARAM(llvm::BasicBlock*, block);
|
||||
|
@ -2542,7 +2632,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
CMD_PARAM(llvm::BasicBlock*, block);
|
||||
mIRBuilder->SetInsertPoint(block, block->begin());
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case BfIRCmd_EraseFromParent:
|
||||
{
|
||||
CMD_PARAM(llvm::BasicBlock*, block);
|
||||
|
@ -3906,7 +3996,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
else
|
||||
{
|
||||
llvm::Type* voidPtrType = llvm::Type::getInt8PtrTy(*mLLVMContext);
|
||||
if (mAsmObjectCheckAsm == NULL)
|
||||
if (mObjectCheckAsm == NULL)
|
||||
{
|
||||
std::vector<llvm::Type*> paramTypes;
|
||||
paramTypes.push_back(voidPtrType);
|
||||
|
@ -3918,7 +4008,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
"int $$3\n"
|
||||
"1:";
|
||||
|
||||
mAsmObjectCheckAsm = llvm::InlineAsm::get(funcType,
|
||||
mObjectCheckAsm = llvm::InlineAsm::get(funcType,
|
||||
asmStr.c_str(), "r,~{dirflag},~{fpsr},~{flags}", true,
|
||||
false, llvm::InlineAsm::AD_ATT);
|
||||
}
|
||||
|
@ -3926,7 +4016,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
llvm::SmallVector<llvm::Value*, 1> llvmArgs;
|
||||
llvmArgs.push_back(mIRBuilder->CreateBitCast(val, voidPtrType));
|
||||
|
||||
llvm::CallInst* callInst = irBuilder->CreateCall(mAsmObjectCheckAsm, llvmArgs);
|
||||
llvm::CallInst* callInst = irBuilder->CreateCall(mObjectCheckAsm, llvmArgs);
|
||||
callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoUnwind);
|
||||
|
||||
SetResult(curId, mIRBuilder->GetInsertBlock());
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace llvm
|
|||
class AttributeList;
|
||||
class Module;
|
||||
class LLVMContext;
|
||||
class TargetMachine;
|
||||
class TargetMachine;
|
||||
};
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
@ -100,7 +100,8 @@ public:
|
|||
llvm::TargetMachine* mLLVMTargetMachine;
|
||||
Array<llvm::DebugLoc> mSavedDebugLocs;
|
||||
llvm::InlineAsm* mNopInlineAsm;
|
||||
llvm::InlineAsm* mAsmObjectCheckAsm;
|
||||
llvm::InlineAsm* mObjectCheckAsm;
|
||||
llvm::InlineAsm* mOverflowCheckAsm;
|
||||
llvm::DebugLoc mDebugLoc;
|
||||
BfCodeGenOptions mCodeGenOptions;
|
||||
bool mHasDebugLoc;
|
||||
|
@ -140,6 +141,7 @@ public:
|
|||
llvm::Type* GetSizeAlignedType(BfIRTypeEntry* typeEntry);
|
||||
llvm::Value* GetAlignedPtr(llvm::Value* val);
|
||||
llvm::Value* FixGEP(llvm::Value* fromValue, llvm::Value* result);
|
||||
llvm::Value* DoCheckedIntrinsic(llvm::Intrinsic::ID intrin, llvm::Value* lhs, llvm::Value* rhs, bool useAsm);
|
||||
|
||||
public:
|
||||
BfIRCodeGen();
|
||||
|
@ -158,6 +160,7 @@ public:
|
|||
void Read(int64& i);
|
||||
void Read(Val128& i);
|
||||
void Read(bool& val);
|
||||
void Read(int8& val);
|
||||
void Read(BfIRTypeEntry*& type);
|
||||
void Read(llvm::Type*& llvmType, BfIRTypeEntry** outTypeEntry = NULL);
|
||||
void Read(llvm::FunctionType*& llvmType);
|
||||
|
|
|
@ -160,6 +160,7 @@ enum BfCompilerOptionFlags
|
|||
BfCompilerOptionFlag_DebugAlloc = 0x8000,
|
||||
BfCompilerOptionFlag_OmitDebugHelpers = 0x10000,
|
||||
BfCompilerOptionFlag_NoFramePointerElim = 0x20000,
|
||||
BfCompilerOptionFlag_ArithmeticChecks = 0x40000,
|
||||
};
|
||||
|
||||
enum BfTypeFlags
|
||||
|
@ -1441,19 +1442,20 @@ enum BfOptionFlags
|
|||
BfOptionFlags_InitLocalVariables = 2,
|
||||
BfOptionFlags_EmitDynamicCastCheck = 4,
|
||||
BfOptionFlags_EmitObjectAccessCheck = 8,
|
||||
BfOptionFlags_ArithmeticCheck = 0x10,
|
||||
|
||||
BfOptionFlags_ReflectAlwaysIncludeType = 0x10,
|
||||
BfOptionFlags_ReflectAlwaysIncludeAll = 0x20,
|
||||
BfOptionFlags_ReflectAssumeInstantiated = 0x40,
|
||||
BfOptionFlags_ReflectBoxing = 0x80,
|
||||
BfOptionFlags_ReflectStaticFields = 0x100,
|
||||
BfOptionFlags_ReflectNonStaticFields = 0x200,
|
||||
BfOptionFlags_ReflectStaticMethods = 0x400,
|
||||
BfOptionFlags_ReflectNonStaticMethods = 0x800,
|
||||
BfOptionFlags_ReflectConstructors = 0x1000,
|
||||
BfOptionFlags_ReflectAlwaysIncludeType = 0x20,
|
||||
BfOptionFlags_ReflectAlwaysIncludeAll = 0x40,
|
||||
BfOptionFlags_ReflectAssumeInstantiated = 0x80,
|
||||
BfOptionFlags_ReflectBoxing = 0x100,
|
||||
BfOptionFlags_ReflectStaticFields = 0x200,
|
||||
BfOptionFlags_ReflectNonStaticFields = 0x400,
|
||||
BfOptionFlags_ReflectStaticMethods = 0x800,
|
||||
BfOptionFlags_ReflectNonStaticMethods = 0x1000,
|
||||
BfOptionFlags_ReflectConstructors = 0x2000,
|
||||
|
||||
BfOptionFlags_Reflect_MethodMask = BfOptionFlags_ReflectStaticMethods | BfOptionFlags_ReflectNonStaticMethods | BfOptionFlags_ReflectConstructors,
|
||||
BfOptionFlags_Mask = 0xFFF
|
||||
BfOptionFlags_Mask = 0x3FFF
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue