зеркало из https://github.com/dotnet/llilc.git
Add makeCall wrapper
This wraps LLVMBuilder->CreateCall, and will be where the logic goes that instead creates an invoke with an appropriate exception edge if we're in a protected region.
This commit is contained in:
Родитель
b60b5bf718
Коммит
9369fba917
|
@ -68,13 +68,14 @@ public:
|
|||
/// \param Reader The \p GenIR instance that will be used to emit
|
||||
/// IR.
|
||||
/// \param Target The call target.
|
||||
/// \param MayThrow True iff the callee may raise an exception
|
||||
/// \param Args The arguments to the call.
|
||||
/// \param IndirectionCell The indirection cell argument for the call, if
|
||||
/// any.
|
||||
/// \param CallNode [out] The call instruction.
|
||||
///
|
||||
/// \returns The result of the call to the target.
|
||||
llvm::Value *emitCall(GenIR &Reader, llvm::Value *Target,
|
||||
llvm::Value *emitCall(GenIR &Reader, llvm::Value *Target, bool mayThrow,
|
||||
llvm::ArrayRef<llvm::Value *> Args,
|
||||
llvm::Value *IndirectionCell,
|
||||
llvm::Value **CallNode) const;
|
||||
|
|
|
@ -3134,15 +3134,16 @@ public:
|
|||
IRNode *ThisArg) = 0;
|
||||
|
||||
// Helper callback used by rdrCall to emit call code.
|
||||
virtual IRNode *genCall(ReaderCallTargetData *CallTargetData,
|
||||
virtual IRNode *genCall(ReaderCallTargetData *CallTargetData, bool MayThrow,
|
||||
std::vector<IRNode *> Args, IRNode **CallNode) = 0;
|
||||
|
||||
virtual bool canMakeDirectCall(ReaderCallTargetData *CallTargetData) = 0;
|
||||
|
||||
// Generate call to helper
|
||||
virtual IRNode *callHelper(CorInfoHelpFunc HelperID, IRNode *Dst,
|
||||
IRNode *Arg1 = nullptr, IRNode *Arg2 = nullptr,
|
||||
IRNode *Arg3 = nullptr, IRNode *Arg4 = nullptr,
|
||||
virtual IRNode *callHelper(CorInfoHelpFunc HelperID, bool MayThrow,
|
||||
IRNode *Dst, IRNode *Arg1 = nullptr,
|
||||
IRNode *Arg2 = nullptr, IRNode *Arg3 = nullptr,
|
||||
IRNode *Arg4 = nullptr,
|
||||
ReaderAlignType Alignment = Reader_AlignUnknown,
|
||||
bool IsVolatile = false, bool NoCtor = false,
|
||||
bool CanMoveUp = false) = 0;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "reader.h"
|
||||
#include "abi.h"
|
||||
#include "abisignature.h"
|
||||
|
@ -719,13 +720,13 @@ public:
|
|||
IRNode *ThisArg) override;
|
||||
|
||||
// Helper callback used by rdrCall to emit call code.
|
||||
IRNode *genCall(ReaderCallTargetData *CallTargetInfo,
|
||||
IRNode *genCall(ReaderCallTargetData *CallTargetInfo, bool MayThrow,
|
||||
std::vector<IRNode *> Args, IRNode **CallNode) override;
|
||||
|
||||
bool canMakeDirectCall(ReaderCallTargetData *CallTargetData) override;
|
||||
|
||||
// Generate call to helper
|
||||
IRNode *callHelper(CorInfoHelpFunc HelperID, IRNode *Dst,
|
||||
IRNode *callHelper(CorInfoHelpFunc HelperID, bool MayThrow, IRNode *Dst,
|
||||
IRNode *Arg1 = nullptr, IRNode *Arg2 = nullptr,
|
||||
IRNode *Arg3 = nullptr, IRNode *Arg4 = nullptr,
|
||||
ReaderAlignType Alignment = Reader_AlignUnknown,
|
||||
|
@ -733,12 +734,13 @@ public:
|
|||
bool CanMoveUp = false) override;
|
||||
|
||||
// Generate call to helper
|
||||
IRNode *callHelperImpl(CorInfoHelpFunc HelperID, llvm::Type *ReturnType,
|
||||
IRNode *Arg1 = nullptr, IRNode *Arg2 = nullptr,
|
||||
IRNode *Arg3 = nullptr, IRNode *Arg4 = nullptr,
|
||||
ReaderAlignType Alignment = Reader_AlignUnknown,
|
||||
bool IsVolatile = false, bool NoCtor = false,
|
||||
bool CanMoveUp = false);
|
||||
llvm::CallSite callHelperImpl(CorInfoHelpFunc HelperID, bool MayThrow,
|
||||
llvm::Type *ReturnType, IRNode *Arg1 = nullptr,
|
||||
IRNode *Arg2 = nullptr, IRNode *Arg3 = nullptr,
|
||||
IRNode *Arg4 = nullptr,
|
||||
ReaderAlignType Alignment = Reader_AlignUnknown,
|
||||
bool IsVolatile = false, bool NoCtor = false,
|
||||
bool CanMoveUp = false);
|
||||
|
||||
/// Generate special generics helper that might need to insert flow. The
|
||||
/// helper is called if NullCheckArg is null at compile-time or if it
|
||||
|
@ -1031,17 +1033,19 @@ private:
|
|||
///
|
||||
/// \param Condition Condition that will trigger the call.
|
||||
/// \param HelperId Id of the call helper.
|
||||
/// \param MayThrow true if the helper call may raise an exception.
|
||||
/// \param ReturnType Return type of the call helper.
|
||||
/// \param Arg1 First helper argument.
|
||||
/// \param Arg2 Second helper argument.
|
||||
/// \param CallReturns true iff the helper call returns.
|
||||
/// \param CallBlockName Name of the basic block that will contain the call.
|
||||
/// \returns Generated call instruction.
|
||||
llvm::CallInst *genConditionalHelperCall(llvm::Value *Condition,
|
||||
CorInfoHelpFunc HelperId,
|
||||
llvm::Type *ReturnType, IRNode *Arg1,
|
||||
IRNode *Arg2, bool CallReturns,
|
||||
const llvm::Twine &CallBlockName);
|
||||
/// \returns Generated call/invoke instruction.
|
||||
llvm::CallSite genConditionalHelperCall(llvm::Value *Condition,
|
||||
CorInfoHelpFunc HelperId,
|
||||
bool MayThrow, llvm::Type *ReturnType,
|
||||
IRNode *Arg1, IRNode *Arg2,
|
||||
bool CallReturns,
|
||||
const llvm::Twine &CallBlockName);
|
||||
|
||||
/// Generate a call to the throw helper if the condition is met.
|
||||
///
|
||||
|
@ -1144,6 +1148,17 @@ private:
|
|||
return makeLoad(Address, IsVolatile, false);
|
||||
}
|
||||
|
||||
/// \brief Create a call or invoke instruction
|
||||
///
|
||||
/// The call is inserted at the LLVMBuilder's current insertion point.
|
||||
///
|
||||
/// \param Callee Target of the call
|
||||
/// \param MayThrow True if the callee may raise an exception
|
||||
/// \param Args Arguments to pass to the callee
|
||||
/// \returns A \p CallSite wrapping the CallInst or InvokeInst
|
||||
llvm::CallSite makeCall(llvm::Value *Callee, bool MayThrow,
|
||||
llvm::ArrayRef<llvm::Value *> Args);
|
||||
|
||||
/// Store a value to an argument passed indirectly.
|
||||
///
|
||||
/// The storage backing such arguments may be loacted on the heap; any stores
|
||||
|
|
|
@ -87,7 +87,7 @@ ABICallSignature::ABICallSignature(const ReaderCallSignature &TheSignature,
|
|||
: ABISignature(TheSignature, Reader, TheABIInfo), Signature(TheSignature) {}
|
||||
|
||||
Value *ABICallSignature::emitCall(GenIR &Reader, llvm::Value *Target,
|
||||
llvm::ArrayRef<Value *> Args,
|
||||
bool MayThrow, llvm::ArrayRef<Value *> Args,
|
||||
llvm::Value *IndirectionCell,
|
||||
llvm::Value **CallNode) const {
|
||||
assert(Target->getType()->isIntegerTy(Reader.TargetPointerSizeInBits));
|
||||
|
@ -150,7 +150,7 @@ Value *ABICallSignature::emitCall(GenIR &Reader, llvm::Value *Target,
|
|||
Type *FunctionPtrTy = Reader.getUnmanagedPointerType(FunctionTy);
|
||||
|
||||
Target = Builder.CreateIntToPtr(Target, FunctionPtrTy);
|
||||
CallInst *Call = Builder.CreateCall(Target, Arguments);
|
||||
CallSite Call = Reader.makeCall(Target, MayThrow, Arguments);
|
||||
|
||||
CallingConv::ID CC;
|
||||
if (HasIndirectionCell) {
|
||||
|
@ -159,18 +159,18 @@ Value *ABICallSignature::emitCall(GenIR &Reader, llvm::Value *Target,
|
|||
} else {
|
||||
CC = getLLVMCallingConv(Signature.getCallingConvention());
|
||||
}
|
||||
Call->setCallingConv(CC);
|
||||
Call.setCallingConv(CC);
|
||||
|
||||
if (ResultNode == nullptr) {
|
||||
assert(!HasIndirectResult);
|
||||
const CallArgType &SigResultType = Signature.getResultType();
|
||||
Type *Ty = Reader.getType(SigResultType.CorType, SigResultType.Class);
|
||||
ResultNode = coerce(Reader, Ty, Call);
|
||||
ResultNode = coerce(Reader, Ty, Call.getInstruction());
|
||||
} else {
|
||||
ResultNode = Builder.CreateLoad(ResultNode);
|
||||
}
|
||||
|
||||
*CallNode = Call;
|
||||
*CallNode = Call.getInstruction();
|
||||
return ResultNode;
|
||||
}
|
||||
|
||||
|
|
|
@ -1309,7 +1309,8 @@ void ReaderBase::insertHelperCall(
|
|||
HelperArgNodes[Index] = CurrentArg;
|
||||
}
|
||||
|
||||
callHelper(AccessAllowedInfo.helperNum, nullptr, HelperArgNodes[0],
|
||||
const bool MayThrow = true;
|
||||
callHelper(AccessAllowedInfo.helperNum, MayThrow, nullptr, HelperArgNodes[0],
|
||||
HelperArgNodes[1], HelperArgNodes[2], HelperArgNodes[3]);
|
||||
}
|
||||
|
||||
|
@ -3685,8 +3686,9 @@ void ReaderBase::cpBlk(IRNode *Count, // byte count
|
|||
IRNode *SrcAddr, // source address
|
||||
IRNode *DestAddr, // dest address
|
||||
ReaderAlignType Alignment, bool IsVolatile) {
|
||||
callHelper(CORINFO_HELP_MEMCPY, nullptr, DestAddr, SrcAddr, Count, nullptr,
|
||||
Alignment, IsVolatile);
|
||||
const bool MayThrow = true;
|
||||
callHelper(CORINFO_HELP_MEMCPY, MayThrow, nullptr, DestAddr, SrcAddr, Count,
|
||||
nullptr, Alignment, IsVolatile);
|
||||
}
|
||||
|
||||
// InitBlk - Creates a memset helper call/intrinsic.
|
||||
|
@ -3694,8 +3696,9 @@ void ReaderBase::initBlk(IRNode *Count, // byte count
|
|||
IRNode *Value, // Value
|
||||
IRNode *DestAddr, // dest address
|
||||
ReaderAlignType Alignment, bool IsVolatile) {
|
||||
callHelper(CORINFO_HELP_MEMSET, nullptr, DestAddr, Value, Count, nullptr,
|
||||
Alignment, IsVolatile);
|
||||
const bool MayThrow = true;
|
||||
callHelper(CORINFO_HELP_MEMSET, MayThrow, nullptr, DestAddr, Value, Count,
|
||||
nullptr, Alignment, IsVolatile);
|
||||
}
|
||||
|
||||
void ReaderBase::initObj(CORINFO_RESOLVED_TOKEN *ResolvedToken,
|
||||
|
@ -3738,7 +3741,8 @@ IRNode *ReaderBase::box(CORINFO_RESOLVED_TOKEN *ResolvedToken, IRNode *Arg2,
|
|||
// from the token.
|
||||
Arg1 = genericTokenToNode(ResolvedToken, true);
|
||||
|
||||
RetVal = callHelper(getBoxHelper(Class), Dst, Arg1, Arg2);
|
||||
const bool MayThrow = true;
|
||||
RetVal = callHelper(getBoxHelper(Class), MayThrow, Dst, Arg1, Arg2);
|
||||
|
||||
return RetVal;
|
||||
}
|
||||
|
@ -3770,12 +3774,14 @@ IRNode *ReaderBase::refAnyVal(IRNode *RefAny,
|
|||
Dst = makePtrDstGCOperand(true);
|
||||
|
||||
// Make the helper call
|
||||
return callHelper(CORINFO_HELP_GETREFANY, Dst, Arg1, RefAny);
|
||||
const bool MayThrow = true;
|
||||
return callHelper(CORINFO_HELP_GETREFANY, MayThrow, Dst, Arg1, RefAny);
|
||||
}
|
||||
|
||||
void ReaderBase::storeElemRefAny(IRNode *Value, IRNode *Index, IRNode *Obj) {
|
||||
// Make the helper call
|
||||
callHelper(CORINFO_HELP_ARRADDR_ST, nullptr, Obj, Index, Value);
|
||||
const bool MayThrow = true;
|
||||
callHelper(CORINFO_HELP_ARRADDR_ST, MayThrow, nullptr, Obj, Index, Value);
|
||||
}
|
||||
|
||||
// StoreIndir - Creates an instruction to assign the value on
|
||||
|
@ -3921,7 +3927,8 @@ IRNode *ReaderBase::unboxAny(CORINFO_RESOLVED_TOKEN *ResolvedToken, IRNode *Arg,
|
|||
// Break - Default reader processing for CEE_BREAK.
|
||||
void ReaderBase::breakOpcode() {
|
||||
// Make the helper call
|
||||
callHelper(CORINFO_HELP_USER_BREAKPOINT, nullptr);
|
||||
const bool MayThrow = true;
|
||||
callHelper(CORINFO_HELP_USER_BREAKPOINT, MayThrow, nullptr);
|
||||
}
|
||||
|
||||
// InsertClassConstructor - Insert a call to the class constructor helper.
|
||||
|
@ -3944,30 +3951,38 @@ void ReaderBase::insertClassConstructor() {
|
|||
methodNeedsToKeepAliveGenericsContext(true);
|
||||
|
||||
switch (Kind.runtimeLookupKind) {
|
||||
case CORINFO_LOOKUP_THISOBJ:
|
||||
case CORINFO_LOOKUP_THISOBJ: {
|
||||
// call CORINFO_HELP_INITINSTCLASS(thisobj, embedMethodHandle(M))
|
||||
Method = embedMethodHandle(Method, &IsIndirect);
|
||||
// TODO: Aliasing -- always readonly?
|
||||
MethodNode = handleToIRNode(MethodToken, Method, 0, IsIndirect,
|
||||
IsIndirect, true, false);
|
||||
ClassNode = derefAddress(thisObj(), false, false);
|
||||
callHelper(CORINFO_HELP_INITINSTCLASS, nullptr, ClassNode, MethodNode);
|
||||
const bool MayThrow = true;
|
||||
callHelper(CORINFO_HELP_INITINSTCLASS, MayThrow, nullptr, ClassNode,
|
||||
MethodNode);
|
||||
return;
|
||||
case CORINFO_LOOKUP_CLASSPARAM:
|
||||
}
|
||||
case CORINFO_LOOKUP_CLASSPARAM: {
|
||||
// will only be returned when you are compiling code that takes
|
||||
// a hidden parameter P. You should emit a call
|
||||
// CORINFO_HELP_INITCLASS(P)
|
||||
ClassNode = instParam();
|
||||
callHelper(CORINFO_HELP_INITCLASS, nullptr, ClassNode);
|
||||
const bool MayThrow = true;
|
||||
callHelper(CORINFO_HELP_INITCLASS, MayThrow, nullptr, ClassNode);
|
||||
return;
|
||||
case CORINFO_LOOKUP_METHODPARAM:
|
||||
}
|
||||
case CORINFO_LOOKUP_METHODPARAM: {
|
||||
// will only be returned when you are compiling code that takes
|
||||
// a hidden parameter P. You should emit a call
|
||||
// CORINFO_HELP_INITINSTCLASS(nullptr, P)
|
||||
MethodNode = instParam();
|
||||
ClassNode = loadConstantI8(0);
|
||||
callHelper(CORINFO_HELP_INITINSTCLASS, nullptr, ClassNode, MethodNode);
|
||||
const bool MayThrow = true;
|
||||
callHelper(CORINFO_HELP_INITINSTCLASS, MayThrow, nullptr, ClassNode,
|
||||
MethodNode);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
ASSERTNR(!"NYI");
|
||||
}
|
||||
|
@ -3987,7 +4002,8 @@ void ReaderBase::insertClassConstructor() {
|
|||
ClassNode = handleToIRNode(MethodToken, ClassHandle, Class, IsIndirect,
|
||||
IsIndirect, true, false);
|
||||
|
||||
callHelper(HelperId, nullptr, ClassNode);
|
||||
const bool MayThrow = false;
|
||||
callHelper(HelperId, MayThrow, nullptr, ClassNode);
|
||||
} else {
|
||||
rdrCallGetStaticBase(Class, MethodToken, HelperId, false, false, nullptr);
|
||||
}
|
||||
|
@ -4032,14 +4048,16 @@ IRNode *ReaderBase::rdrGetCritSect() {
|
|||
// In this case, the hidden param is the class handle.
|
||||
HandleNode = instParam();
|
||||
break;
|
||||
case CORINFO_LOOKUP_METHODPARAM:
|
||||
case CORINFO_LOOKUP_METHODPARAM: {
|
||||
// In this case, the hidden param is the method handle.
|
||||
HandleNode = instParam();
|
||||
// Call helper CORINFO_HELP_GETCLASSFROMMETHODPARAM to get the
|
||||
// class handle from the method handle.
|
||||
HandleNode = callHelper(CORINFO_HELP_GETCLASSFROMMETHODPARAM,
|
||||
const bool MayThrow = false;
|
||||
HandleNode = callHelper(CORINFO_HELP_GETCLASSFROMMETHODPARAM, MayThrow,
|
||||
makePtrNode(), HandleNode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ASSERTNR(!"Unknown LOOKUP_KIND");
|
||||
break;
|
||||
|
@ -4049,8 +4067,9 @@ IRNode *ReaderBase::rdrGetCritSect() {
|
|||
// CORINFO_CLASS_HANDLE for the exact class.
|
||||
|
||||
// Given the class handle, get the pointer to the Monitor.
|
||||
HandleNode = callHelper(CORINFO_HELP_GETSYNCFROMCLASSHANDLE, makePtrNode(),
|
||||
HandleNode);
|
||||
const bool MayThrow = false;
|
||||
HandleNode = callHelper(CORINFO_HELP_GETSYNCFROMCLASSHANDLE, MayThrow,
|
||||
makePtrNode(), HandleNode);
|
||||
}
|
||||
|
||||
ASSERTNR(HandleNode);
|
||||
|
@ -4101,7 +4120,8 @@ void ReaderBase::rdrCallFieldHelper(
|
|||
IsIndirect, IsIndirect, true, false);
|
||||
|
||||
// Make the helper call
|
||||
callHelper(HelperId, nullptr, Arg1, Arg2, Arg3, Arg4, Alignment,
|
||||
const bool MayThrow = true;
|
||||
callHelper(HelperId, MayThrow, nullptr, Arg1, Arg2, Arg3, Arg4, Alignment,
|
||||
IsVolatile);
|
||||
} else {
|
||||
// OTHER LOAD
|
||||
|
@ -4113,8 +4133,9 @@ void ReaderBase::rdrCallFieldHelper(
|
|||
Arg1 = Obj;
|
||||
|
||||
// Make the helper call
|
||||
callHelper(HelperId, Dst, Arg1, Arg2, nullptr, nullptr, Alignment,
|
||||
IsVolatile);
|
||||
const bool MayThrow = true;
|
||||
callHelper(HelperId, MayThrow, Dst, Arg1, Arg2, nullptr, nullptr,
|
||||
Alignment, IsVolatile);
|
||||
}
|
||||
} else {
|
||||
// STORE
|
||||
|
@ -4147,7 +4168,8 @@ void ReaderBase::rdrCallFieldHelper(
|
|||
Arg1 = Obj;
|
||||
|
||||
// Make the helper call
|
||||
callHelper(HelperId, nullptr, Arg1, Arg2, Arg3, Arg4, Alignment,
|
||||
const bool MayThrow = true;
|
||||
callHelper(HelperId, MayThrow, nullptr, Arg1, Arg2, Arg3, Arg4, Alignment,
|
||||
IsVolatile);
|
||||
} else {
|
||||
// assert that the helper id is expected
|
||||
|
@ -4168,8 +4190,9 @@ void ReaderBase::rdrCallFieldHelper(
|
|||
Arg1 = Obj;
|
||||
|
||||
// Make the helper call
|
||||
callHelper(HelperId, nullptr, Arg1, Arg2, Arg3, nullptr, Alignment,
|
||||
IsVolatile);
|
||||
const bool MayThrow = true;
|
||||
callHelper(HelperId, MayThrow, nullptr, Arg1, Arg2, Arg3, nullptr,
|
||||
Alignment, IsVolatile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4202,9 +4225,10 @@ void ReaderBase::rdrCallWriteBarrierHelper(
|
|||
// writing to a field in a class which happens to be a GC pointer.
|
||||
//
|
||||
// HCIMPL2(void, JIT_CheckedWriteBarrier, Object** dest, Object * value)
|
||||
callHelper(IsUnchecked ? CORINFO_HELP_ASSIGN_REF
|
||||
: CORINFO_HELP_CHECKED_ASSIGN_REF,
|
||||
nullptr, Dst, Src, nullptr, nullptr, Alignment, IsVolatile);
|
||||
const bool MayThrow = true;
|
||||
callHelper(
|
||||
IsUnchecked ? CORINFO_HELP_ASSIGN_REF : CORINFO_HELP_CHECKED_ASSIGN_REF,
|
||||
MayThrow, nullptr, Dst, Src, nullptr, nullptr, Alignment, IsVolatile);
|
||||
} else {
|
||||
// This is the case in which we will be copying a value class into
|
||||
// the field of this struct. The runtime will need to be passed
|
||||
|
@ -4242,13 +4266,15 @@ void ReaderBase::rdrCallWriteBarrierHelper(
|
|||
handleToIRNode(ResolvedToken->token, ClassHandle, Class, IsIndirect,
|
||||
IsIndirect, true, false);
|
||||
|
||||
callHelper(CORINFO_HELP_ASSIGN_STRUCT, nullptr, Dst, Src, ClassHandleNode,
|
||||
nullptr, Alignment, IsVolatile);
|
||||
const bool MayThrow = true;
|
||||
callHelper(CORINFO_HELP_ASSIGN_STRUCT, MayThrow, nullptr, Dst, Src,
|
||||
ClassHandleNode, nullptr, Alignment, IsVolatile);
|
||||
} else {
|
||||
// If the class doesn't have a gc layout then use a memcopy
|
||||
IRNode *Size = loadConstantI4(getClassSize(Class));
|
||||
callHelper(CORINFO_HELP_MEMCPY, nullptr, Dst, Src, Size, nullptr,
|
||||
Alignment, IsVolatile);
|
||||
const bool MayThrow = true;
|
||||
callHelper(CORINFO_HELP_MEMCPY, MayThrow, nullptr, Dst, Src, Size,
|
||||
nullptr, Alignment, IsVolatile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4285,9 +4311,10 @@ IRNode *ReaderBase::rdrCallGetStaticBase(CORINFO_CLASS_HANDLE Class,
|
|||
Token, EmbedClassDomainID, (CORINFO_CLASS_HANDLE)((size_t)Class | 1),
|
||||
IsIndirect2, IsIndirect2, IsIndirect2, false);
|
||||
|
||||
return callHelper(HelperId, Dst, ModuleDomainIDNode, ClassDomainIDNode,
|
||||
nullptr, nullptr, Reader_AlignUnknown, false, NoCtor,
|
||||
CanMoveUp);
|
||||
const bool MayThrow = false;
|
||||
return callHelper(HelperId, MayThrow, Dst, ModuleDomainIDNode,
|
||||
ClassDomainIDNode, nullptr, nullptr, Reader_AlignUnknown,
|
||||
false, NoCtor, CanMoveUp);
|
||||
}
|
||||
|
||||
IRNode *
|
||||
|
@ -4308,7 +4335,9 @@ ReaderBase::rdrGetStaticFieldAddress(CORINFO_RESOLVED_TOKEN *ResolvedToken,
|
|||
IRNode *PointerNode = makePtrDstGCOperand(true);
|
||||
|
||||
// Now make the call and attach the arguments.
|
||||
return callHelper(FieldInfo->helper, PointerNode, FieldHandleNode);
|
||||
const bool MayThrow = false;
|
||||
return callHelper(FieldInfo->helper, MayThrow, PointerNode,
|
||||
FieldHandleNode);
|
||||
}
|
||||
|
||||
case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER:
|
||||
|
@ -4331,8 +4360,9 @@ ReaderBase::rdrGetStaticFieldAddress(CORINFO_RESOLVED_TOKEN *ResolvedToken,
|
|||
IRNode *TempNode = makePtrNode(Reader_PtrGcInterior);
|
||||
|
||||
// Now make the call and attach the arguments.
|
||||
const bool MayThrow = false;
|
||||
SharedStaticsBaseNode =
|
||||
callHelper(FieldInfo->helper, TempNode, ClassHandleNode);
|
||||
callHelper(FieldInfo->helper, MayThrow, TempNode, ClassHandleNode);
|
||||
} else {
|
||||
CorInfoHelpFunc HelperId = FieldInfo->helper;
|
||||
CORINFO_CLASS_HANDLE Class = ResolvedToken->hClass;
|
||||
|
@ -4585,7 +4615,8 @@ IRNode *ReaderBase::rdrGetFieldAddress(CORINFO_RESOLVED_TOKEN *ResolvedToken,
|
|||
Dst = makePtrNode();
|
||||
}
|
||||
|
||||
return callHelper(FieldInfo->helper, Dst, Arg1, Arg2);
|
||||
const bool MayThrow = true;
|
||||
return callHelper(FieldInfo->helper, MayThrow, Dst, Arg1, Arg2);
|
||||
} else {
|
||||
// Get the offset, add it to the this pointer to calculate the
|
||||
// actual address of the field.
|
||||
|
@ -4812,6 +4843,7 @@ ReaderBase::rdrCall(ReaderCallTargetData *Data, ReaderBaseNS::CallOpcode Opcode,
|
|||
// For certain intrinsics, we can determine that the call has no
|
||||
// side effects ...
|
||||
bool CallCanSideEffect = true;
|
||||
bool MayThrow = true;
|
||||
|
||||
// TODO: readonly work for calls
|
||||
|
||||
|
@ -5304,7 +5336,7 @@ ReaderBase::rdrCall(ReaderCallTargetData *Data, ReaderBaseNS::CallOpcode Opcode,
|
|||
}
|
||||
|
||||
// Ask GenIR to emit call, optionally returns a ReturnNode.
|
||||
ReturnNode = genCall(Data, Arguments, CallNode);
|
||||
ReturnNode = genCall(Data, MayThrow, Arguments, CallNode);
|
||||
|
||||
if (Data->isNewObj()) {
|
||||
ReturnNode = rdrMakeNewObjReturnNode(Data, NewObjThisArg, ReturnNode);
|
||||
|
@ -5508,7 +5540,8 @@ IRNode *ReaderBase::rdrGetIndirectVirtualCallTarget(
|
|||
// Get the address of the target function by calling helper.
|
||||
// Type it as a native int, it will be recast later.
|
||||
IRNode *Dst = loadConstantI(0);
|
||||
return callHelper(CORINFO_HELP_VIRTUAL_FUNC_PTR, Dst, ThisPtrCopy,
|
||||
const bool MayThrow = true;
|
||||
return callHelper(CORINFO_HELP_VIRTUAL_FUNC_PTR, MayThrow, Dst, ThisPtrCopy,
|
||||
ClassHandle, MethodHandle);
|
||||
}
|
||||
|
||||
|
@ -5635,7 +5668,9 @@ void ReaderBase::rdrInsertCalloutForDelegate(CORINFO_CLASS_HANDLE DelegateType,
|
|||
IsIndirect, IsIndirect, true, false);
|
||||
|
||||
// Make the helper call
|
||||
callHelper(CORINFO_HELP_DELEGATE_SECURITY_CHECK, nullptr, Arg1, Arg2);
|
||||
const bool MayThrow = true;
|
||||
callHelper(CORINFO_HELP_DELEGATE_SECURITY_CHECK, MayThrow, nullptr, Arg1,
|
||||
Arg2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6191,7 +6226,8 @@ void ReaderBase::domInfoRecordClassInit(FlowGraphNode *Fg,
|
|||
// Default routine to insert verification throw.
|
||||
void ReaderBase::insertThrow(CorInfoHelpFunc ThrowHelper, uint32_t Offset) {
|
||||
IRNode *IntConstant = loadConstantI4(Offset);
|
||||
callHelper(ThrowHelper, nullptr, IntConstant);
|
||||
const bool MayThrow = true;
|
||||
callHelper(ThrowHelper, MayThrow, nullptr, IntConstant);
|
||||
}
|
||||
|
||||
// Macro used by main reader loop for distinguishing verify-only passes
|
||||
|
|
|
@ -410,10 +410,11 @@ void GenIR::readerPrePass(uint8_t *Buffer, uint32_t NumBytes) {
|
|||
Value *Condition = LLVMBuilder->CreateIsNotNull(JustMyCodeFlag, "JMC");
|
||||
IRNode *Zero = loadConstantI4(0);
|
||||
Type *Void = Type::getVoidTy(*JitContext->LLVMContext);
|
||||
const bool MayThrow = false;
|
||||
const bool CallReturns = true;
|
||||
genConditionalHelperCall(
|
||||
Condition, CorInfoHelpFunc::CORINFO_HELP_DBG_IS_JUST_MY_CODE, Void,
|
||||
JustMyCodeFlag, Zero, CallReturns, "JustMyCodeHook");
|
||||
Condition, CorInfoHelpFunc::CORINFO_HELP_DBG_IS_JUST_MY_CODE,
|
||||
MayThrow, Void, JustMyCodeFlag, Zero, CallReturns, "JustMyCodeHook");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,7 +511,8 @@ void GenIR::insertIRToKeepGenericContextAlive() {
|
|||
Value *FrameEscape = Intrinsic::getDeclaration(JitContext->CurrentModule,
|
||||
Intrinsic::frameescape);
|
||||
Value *Args[] = {ContextLocalAddress};
|
||||
LLVMBuilder->CreateCall(FrameEscape, Args);
|
||||
const bool MayThrow = false;
|
||||
makeCall(FrameEscape, MayThrow, Args);
|
||||
// Don't move TempInsertionPoint up since what we added was not an alloca
|
||||
LLVMBuilder->restoreIP(SavedInsertPoint);
|
||||
|
||||
|
@ -545,7 +547,8 @@ void GenIR::insertIRForSecurityObject() {
|
|||
IsIndirect, IsRelocatable, IsCallTarget);
|
||||
CorInfoHelpFunc SecurityHelper =
|
||||
JitContext->JitInfo->getSecurityPrologHelper(MethodHandle);
|
||||
callHelper(SecurityHelper, nullptr, MethodNode,
|
||||
const bool MayThrow = true;
|
||||
callHelper(SecurityHelper, MayThrow, nullptr, MethodNode,
|
||||
(IRNode *)SecurityObjectAddress);
|
||||
|
||||
LLVMBuilder->restoreIP(SavedInsertPoint);
|
||||
|
@ -566,7 +569,8 @@ void GenIR::callMonitorHelper(bool IsEnter) {
|
|||
} else {
|
||||
HelperId = IsEnter ? CORINFO_HELP_MON_ENTER : CORINFO_HELP_MON_EXIT;
|
||||
}
|
||||
callHelperImpl(HelperId, Type::getVoidTy(*JitContext->LLVMContext),
|
||||
const bool MayThrow = false;
|
||||
callHelperImpl(HelperId, MayThrow, Type::getVoidTy(*JitContext->LLVMContext),
|
||||
MethodSyncHandle, (IRNode *)SyncFlag);
|
||||
}
|
||||
|
||||
|
@ -2499,13 +2503,17 @@ IRNode *GenIR::binaryOp(ReaderBaseNS::BinaryOpcode Opcode, IRNode *Arg1,
|
|||
llvm_unreachable("Bad floating point type!");
|
||||
}
|
||||
|
||||
Result = callHelperImpl(Helper, ResultType, Arg1, Arg2);
|
||||
const bool MayThrow = false;
|
||||
Result = (IRNode *)callHelperImpl(Helper, MayThrow, ResultType, Arg1, Arg2)
|
||||
.getInstruction();
|
||||
} else if (IsOverflow) {
|
||||
// Call the appropriate intrinsic. Its result is a pair of the arithmetic
|
||||
// result and a bool indicating whether the operation overflows.
|
||||
Value *Intrinsic = Intrinsic::getDeclaration(
|
||||
JitContext->CurrentModule, Triple[Opcode].Op.Intrinsic, ResultType);
|
||||
Value *Pair = LLVMBuilder->CreateCall2(Intrinsic, Arg1, Arg2);
|
||||
Value *Args[] = {Arg1, Arg2};
|
||||
const bool MayThrow = false;
|
||||
Value *Pair = makeCall(Intrinsic, MayThrow, Args).getInstruction();
|
||||
|
||||
// Extract the bool and raise an overflow exception if set.
|
||||
Value *OvfBool = LLVMBuilder->CreateExtractValue(Pair, 1, "Ovf");
|
||||
|
@ -3067,6 +3075,13 @@ LoadInst *GenIR::makeLoad(Value *Address, bool IsVolatile,
|
|||
return LLVMBuilder->CreateLoad(Address, IsVolatile);
|
||||
}
|
||||
|
||||
CallSite GenIR::makeCall(Value *Callee, bool MayThrow, ArrayRef<Value *> Args) {
|
||||
if (MayThrow) {
|
||||
// TODO: Generate an invoke with an appropriate unwind label.
|
||||
}
|
||||
return LLVMBuilder->CreateCall(Callee, Args);
|
||||
}
|
||||
|
||||
void GenIR::storeStaticField(CORINFO_RESOLVED_TOKEN *FieldToken,
|
||||
IRNode *ValueToStore, bool IsVolatile) {
|
||||
// Gather information about the field
|
||||
|
@ -3233,8 +3248,10 @@ IRNode *GenIR::loadElemA(CORINFO_RESOLVED_TOKEN *ResolvedToken, IRNode *Index,
|
|||
if (!IsReadOnly && ((ClassAttribs & CORINFO_FLG_VALUECLASS) == 0)) {
|
||||
IRNode *HandleNode = genericTokenToNode(ResolvedToken);
|
||||
PointerType *ElementAddressTy = getManagedPointerType(ElementTy);
|
||||
return callHelperImpl(CORINFO_HELP_LDELEMA_REF, ElementAddressTy, Array,
|
||||
Index, HandleNode);
|
||||
const bool MayThrow = true;
|
||||
return (IRNode *)callHelperImpl(CORINFO_HELP_LDELEMA_REF, MayThrow,
|
||||
ElementAddressTy, Array, Index,
|
||||
HandleNode).getInstruction();
|
||||
}
|
||||
|
||||
return genArrayElemAddress(Array, Index, ElementTy);
|
||||
|
@ -3402,21 +3419,23 @@ bool isNonVolatileWriteHelperCall(CorInfoHelpFunc HelperId) {
|
|||
}
|
||||
|
||||
// Generate call to helper
|
||||
IRNode *GenIR::callHelper(CorInfoHelpFunc HelperID, IRNode *Dst, IRNode *Arg1,
|
||||
IRNode *Arg2, IRNode *Arg3, IRNode *Arg4,
|
||||
ReaderAlignType Alignment, bool IsVolatile,
|
||||
bool NoCtor, bool CanMoveUp) {
|
||||
IRNode *GenIR::callHelper(CorInfoHelpFunc HelperID, bool MayThrow, IRNode *Dst,
|
||||
IRNode *Arg1, IRNode *Arg2, IRNode *Arg3,
|
||||
IRNode *Arg4, ReaderAlignType Alignment,
|
||||
bool IsVolatile, bool NoCtor, bool CanMoveUp) {
|
||||
LLVMContext &LLVMContext = *this->JitContext->LLVMContext;
|
||||
Type *ReturnType =
|
||||
(Dst == nullptr) ? Type::getVoidTy(LLVMContext) : Dst->getType();
|
||||
return callHelperImpl(HelperID, ReturnType, Arg1, Arg2, Arg3, Arg4, Alignment,
|
||||
IsVolatile, NoCtor, CanMoveUp);
|
||||
return (IRNode *)callHelperImpl(HelperID, MayThrow, ReturnType, Arg1, Arg2,
|
||||
Arg3, Arg4, Alignment, IsVolatile, NoCtor,
|
||||
CanMoveUp).getInstruction();
|
||||
}
|
||||
|
||||
IRNode *GenIR::callHelperImpl(CorInfoHelpFunc HelperID, Type *ReturnType,
|
||||
IRNode *Arg1, IRNode *Arg2, IRNode *Arg3,
|
||||
IRNode *Arg4, ReaderAlignType Alignment,
|
||||
bool IsVolatile, bool NoCtor, bool CanMoveUp) {
|
||||
CallSite GenIR::callHelperImpl(CorInfoHelpFunc HelperID, bool MayThrow,
|
||||
Type *ReturnType, IRNode *Arg1, IRNode *Arg2,
|
||||
IRNode *Arg3, IRNode *Arg4,
|
||||
ReaderAlignType Alignment, bool IsVolatile,
|
||||
bool NoCtor, bool CanMoveUp) {
|
||||
ASSERT(HelperID != CORINFO_HELP_UNDEF);
|
||||
|
||||
// TODO: We can turn some of these helper calls into intrinsics.
|
||||
|
@ -3463,7 +3482,7 @@ IRNode *GenIR::callHelperImpl(CorInfoHelpFunc HelperID, Type *ReturnType,
|
|||
|
||||
// This is an intermediate result. Callers must handle
|
||||
// transitioning to a valid stack type, if appropriate.
|
||||
IRNode *Call = (IRNode *)LLVMBuilder->CreateCall(Target, Arguments);
|
||||
CallSite Call = makeCall(Target, MayThrow, Arguments);
|
||||
|
||||
if (IsVolatile && isNonVolatileWriteHelperCall(HelperID)) {
|
||||
// TODO: this is only needed where CLRConfig::INTERNAL_JitLockWrite is set
|
||||
|
@ -3500,7 +3519,9 @@ IRNode *GenIR::callRuntimeHandleHelper(CorInfoHelpFunc Helper, IRNode *Arg1,
|
|||
|
||||
// Call the helper unconditionally if NullCheckArg is null.
|
||||
if ((NullCheckArg == nullptr) || isConstantNull(NullCheckArg)) {
|
||||
return callHelperImpl(Helper, ReturnType, Arg1, Arg2);
|
||||
const bool MayThrow = true;
|
||||
return (IRNode *)callHelperImpl(Helper, MayThrow, ReturnType, Arg1, Arg2)
|
||||
.getInstruction();
|
||||
}
|
||||
|
||||
BasicBlock *SaveBlock = LLVMBuilder->GetInsertBlock();
|
||||
|
@ -3509,10 +3530,11 @@ IRNode *GenIR::callRuntimeHandleHelper(CorInfoHelpFunc Helper, IRNode *Arg1,
|
|||
Value *Compare = LLVMBuilder->CreateIsNull(NullCheckArg, "NullCheck");
|
||||
|
||||
// Generate conditional helper call.
|
||||
bool CallReturns = true;
|
||||
CallInst *HelperCall =
|
||||
genConditionalHelperCall(Compare, Helper, ReturnType, Arg1, Arg2,
|
||||
CallReturns, "RuntimeHandleHelperCall");
|
||||
const bool MayThrow = true;
|
||||
const bool CallReturns = true;
|
||||
CallSite HelperCall =
|
||||
genConditionalHelperCall(Compare, Helper, MayThrow, ReturnType, Arg1,
|
||||
Arg2, CallReturns, "RuntimeHandleHelperCall");
|
||||
|
||||
// The result is a PHI of NullCheckArg and the generated call.
|
||||
// The generated code is equivalent to
|
||||
|
@ -3523,9 +3545,9 @@ IRNode *GenIR::callRuntimeHandleHelper(CorInfoHelpFunc Helper, IRNode *Arg1,
|
|||
// return x;
|
||||
BasicBlock *CurrentBlock = LLVMBuilder->GetInsertBlock();
|
||||
BasicBlock *CallBlock = HelperCall->getParent();
|
||||
PHINode *PHI =
|
||||
mergeConditionalResults(CurrentBlock, NullCheckArg, SaveBlock, HelperCall,
|
||||
CallBlock, "RuntimeHandle");
|
||||
PHINode *PHI = mergeConditionalResults(CurrentBlock, NullCheckArg, SaveBlock,
|
||||
HelperCall.getInstruction(), CallBlock,
|
||||
"RuntimeHandle");
|
||||
return (IRNode *)PHI;
|
||||
}
|
||||
|
||||
|
@ -3546,11 +3568,12 @@ IRNode *GenIR::convertHandle(IRNode *GetTokenNumericNode,
|
|||
// Get the value that should be assigned to the struct's field, e.g., an
|
||||
// instance of RuntimeType.
|
||||
Type *HelperResultType = FieldAddress->getType()->getPointerElementType();
|
||||
IRNode *HelperResult =
|
||||
callHelperImpl(HelperID, HelperResultType, GetTokenNumericNode);
|
||||
const bool MayThrow = true;
|
||||
CallSite HelperResult =
|
||||
callHelperImpl(HelperID, MayThrow, HelperResultType, GetTokenNumericNode);
|
||||
|
||||
// Assign the field of the result struct.
|
||||
LLVMBuilder->CreateStore(HelperResult, FieldAddress);
|
||||
LLVMBuilder->CreateStore(HelperResult.getInstruction(), FieldAddress);
|
||||
|
||||
const bool IsVolatile = false;
|
||||
return (IRNode *)LLVMBuilder->CreateLoad(Result, IsVolatile);
|
||||
|
@ -3652,7 +3675,8 @@ IRNode *GenIR::genNewMDArrayCall(ReaderCallTargetData *CallTargetData,
|
|||
getUnmanagedPointerType(FunctionType));
|
||||
|
||||
// Replace the old call instruction with the new one.
|
||||
*CallNode = (IRNode *)LLVMBuilder->CreateCall(Callee, Arguments);
|
||||
const bool MayThrow = true;
|
||||
*CallNode = (IRNode *)makeCall(Callee, MayThrow, Arguments).getInstruction();
|
||||
return *CallNode;
|
||||
}
|
||||
|
||||
|
@ -3704,8 +3728,10 @@ IRNode *GenIR::genNewObjThisArg(ReaderCallTargetData *CallTargetData,
|
|||
|
||||
// Create the address operand for the newobj helper.
|
||||
CorInfoHelpFunc HelperId = getNewHelper(CallTargetData->getResolvedToken());
|
||||
const bool MayThrow = true;
|
||||
Value *ThisPointer =
|
||||
callHelperImpl(HelperId, ThisType, CallTargetData->getClassHandleNode());
|
||||
callHelperImpl(HelperId, MayThrow, ThisType,
|
||||
CallTargetData->getClassHandleNode()).getInstruction();
|
||||
return (IRNode *)ThisPointer;
|
||||
}
|
||||
|
||||
|
@ -3736,7 +3762,7 @@ IRNode *GenIR::genNewObjReturnNode(ReaderCallTargetData *CallTargetData,
|
|||
return ThisArg;
|
||||
}
|
||||
|
||||
IRNode *GenIR::genCall(ReaderCallTargetData *CallTargetInfo,
|
||||
IRNode *GenIR::genCall(ReaderCallTargetData *CallTargetInfo, bool MayThrow,
|
||||
std::vector<IRNode *> Args, IRNode **CallNode) {
|
||||
IRNode *Call = nullptr, *ReturnNode = nullptr;
|
||||
IRNode *TargetNode = CallTargetInfo->getCallTargetNode();
|
||||
|
@ -3815,7 +3841,7 @@ IRNode *GenIR::genCall(ReaderCallTargetData *CallTargetInfo,
|
|||
|
||||
ABICallSignature ABICallSig(Signature, *this, *JitContext->TheABIInfo);
|
||||
Value *ResultNode = ABICallSig.emitCall(
|
||||
*this, (Value *)TargetNode, Arguments,
|
||||
*this, (Value *)TargetNode, MayThrow, Arguments,
|
||||
(Value *)CallTargetInfo->getIndirectionCellNode(), (Value **)&Call);
|
||||
|
||||
// Add VarArgs cookie to outgoing param list
|
||||
|
@ -3907,7 +3933,9 @@ Value *GenIR::genConvertOverflowCheck(Value *Source, IntegerType *TargetTy,
|
|||
}
|
||||
|
||||
// Call the helper to convert to int.
|
||||
Source = callHelperImpl(Helper, HelperResultTy, (IRNode *)Source);
|
||||
const bool MayThrow = true;
|
||||
Source = callHelperImpl(Helper, MayThrow, HelperResultTy, (IRNode *)Source)
|
||||
.getInstruction();
|
||||
SourceTy = HelperResultTy;
|
||||
|
||||
// The result of the helper call already has the requested signedness.
|
||||
|
@ -4372,7 +4400,10 @@ IRNode *GenIR::unbox(CORINFO_RESOLVED_TOKEN *ResolvedToken, IRNode *Object,
|
|||
|
||||
// Call helper to do the type check and get the address of the unbox payload.
|
||||
Type *PtrTy = getType(CorInfoType::CORINFO_TYPE_BYREF, ClassHandle);
|
||||
IRNode *Result = callHelperImpl(HelperId, PtrTy, ClassHandleArgument, Object);
|
||||
const bool MayThrow = true;
|
||||
IRNode *Result =
|
||||
(IRNode *)callHelperImpl(HelperId, MayThrow, PtrTy, ClassHandleArgument,
|
||||
Object).getInstruction();
|
||||
|
||||
// If requested, load the object onto the evaluation stack.
|
||||
if (AndLoad) {
|
||||
|
@ -4417,26 +4448,26 @@ void GenIR::switchOpcode(IRNode *Opr) {
|
|||
void GenIR::throwOpcode(IRNode *Arg1) {
|
||||
// Using a call for now; this will need to be invoke
|
||||
// when we get EH flow properly modeled.
|
||||
CallInst *ThrowCall =
|
||||
(CallInst *)callHelper(CORINFO_HELP_THROW, nullptr, Arg1);
|
||||
Type *Void = Type::getVoidTy(*JitContext->LLVMContext);
|
||||
const bool MayThrow = true;
|
||||
CallSite ThrowCall = callHelperImpl(CORINFO_HELP_THROW, MayThrow, Void, Arg1);
|
||||
|
||||
// Annotate the helper
|
||||
ThrowCall->setDoesNotReturn();
|
||||
ThrowCall.setDoesNotReturn();
|
||||
}
|
||||
|
||||
CallInst *GenIR::genConditionalHelperCall(Value *Condition,
|
||||
CorInfoHelpFunc HelperId,
|
||||
Type *ReturnType, IRNode *Arg1,
|
||||
IRNode *Arg2, bool CallReturns,
|
||||
const Twine &CallBlockName) {
|
||||
CallSite GenIR::genConditionalHelperCall(
|
||||
Value *Condition, CorInfoHelpFunc HelperId, bool MayThrow, Type *ReturnType,
|
||||
IRNode *Arg1, IRNode *Arg2, bool CallReturns, const Twine &CallBlockName) {
|
||||
// Create the call block and fill it in.
|
||||
BasicBlock *CallBlock = createPointBlock(CallBlockName);
|
||||
IRBuilder<>::InsertPoint SavedInsertPoint = LLVMBuilder->saveIP();
|
||||
LLVMBuilder->SetInsertPoint(CallBlock);
|
||||
CallInst *HelperCall =
|
||||
(CallInst *)callHelperImpl(HelperId, ReturnType, Arg1, Arg2);
|
||||
CallSite HelperCall =
|
||||
callHelperImpl(HelperId, MayThrow, ReturnType, Arg1, Arg2);
|
||||
|
||||
if (!CallReturns) {
|
||||
HelperCall->setDoesNotReturn();
|
||||
HelperCall.setDoesNotReturn();
|
||||
LLVMBuilder->CreateUnreachable();
|
||||
}
|
||||
LLVMBuilder->restoreIP(SavedInsertPoint);
|
||||
|
@ -4453,9 +4484,10 @@ void GenIR::genConditionalThrow(Value *Condition, CorInfoHelpFunc HelperId,
|
|||
const Twine &ThrowBlockName) {
|
||||
IRNode *Arg1 = nullptr, *Arg2 = nullptr;
|
||||
Type *ReturnType = Type::getVoidTy(*JitContext->LLVMContext);
|
||||
bool CallReturns = false;
|
||||
genConditionalHelperCall(Condition, HelperId, ReturnType, Arg1, Arg2,
|
||||
CallReturns, ThrowBlockName);
|
||||
const bool MayThrow = true;
|
||||
const bool CallReturns = false;
|
||||
genConditionalHelperCall(Condition, HelperId, MayThrow, ReturnType, Arg1,
|
||||
Arg2, CallReturns, ThrowBlockName);
|
||||
}
|
||||
|
||||
IRNode *GenIR::genNullCheck(IRNode *Node) {
|
||||
|
@ -4943,8 +4975,10 @@ IRNode *GenIR::loadVirtFunc(IRNode *Arg1, CORINFO_RESOLVED_TOKEN *ResolvedToken,
|
|||
|
||||
Type *Ty =
|
||||
Type::getIntNTy(*this->JitContext->LLVMContext, TargetPointerSizeInBits);
|
||||
IRNode *CodeAddress = callHelperImpl(CORINFO_HELP_VIRTUAL_FUNC_PTR, Ty, Arg1,
|
||||
TypeToken, MethodToken);
|
||||
const bool MayThrow = true;
|
||||
IRNode *CodeAddress =
|
||||
(IRNode *)callHelperImpl(CORINFO_HELP_VIRTUAL_FUNC_PTR, MayThrow, Ty,
|
||||
Arg1, TypeToken, MethodToken).getInstruction();
|
||||
|
||||
return CodeAddress;
|
||||
}
|
||||
|
@ -5335,8 +5369,9 @@ IRNode *GenIR::newArr(CORINFO_RESOLVED_TOKEN *ResolvedToken, IRNode *Arg1) {
|
|||
getType(CorInfoType::CORINFO_TYPE_CLASS, ResolvedToken->hClass);
|
||||
Value *Destination = Constant::getNullValue(ArrayType);
|
||||
|
||||
return callHelper(getNewArrHelper(ElementType), (IRNode *)Destination, Token,
|
||||
NumOfElements);
|
||||
const bool MayThrow = true;
|
||||
return callHelper(getNewArrHelper(ElementType), MayThrow,
|
||||
(IRNode *)Destination, Token, NumOfElements);
|
||||
}
|
||||
|
||||
// CastOp - Generates code for castclass or isinst.
|
||||
|
@ -5388,9 +5423,11 @@ IRNode *GenIR::castOp(CORINFO_RESOLVED_TOKEN *ResolvedToken, IRNode *ObjRefNode,
|
|||
// Generate the helper call or intrinsic
|
||||
const bool IsVolatile = false;
|
||||
const bool DoesNotInvokeStaticCtor = Optimize;
|
||||
return callHelperImpl(HelperId, ResultType, ClassHandleNode, ObjRefNode,
|
||||
nullptr, nullptr, Reader_AlignUnknown, IsVolatile,
|
||||
DoesNotInvokeStaticCtor);
|
||||
const bool MayThrow = true;
|
||||
return (IRNode *)callHelperImpl(HelperId, MayThrow, ResultType,
|
||||
ClassHandleNode, ObjRefNode, nullptr, nullptr,
|
||||
Reader_AlignUnknown, IsVolatile,
|
||||
DoesNotInvokeStaticCtor).getInstruction();
|
||||
}
|
||||
|
||||
// Override the cast class optimization
|
||||
|
@ -5416,7 +5453,8 @@ bool GenIR::abs(IRNode *Argument, IRNode **Result) {
|
|||
Type *Types[] = {Ty};
|
||||
Value *FAbs = Intrinsic::getDeclaration(JitContext->CurrentModule,
|
||||
Intrinsic::fabs, Types);
|
||||
Value *Abs = LLVMBuilder->CreateCall(FAbs, Argument);
|
||||
bool MayThrow = false;
|
||||
Value *Abs = makeCall(FAbs, MayThrow, Argument).getInstruction();
|
||||
*Result = (IRNode *)Abs;
|
||||
return true;
|
||||
}
|
||||
|
@ -5438,9 +5476,10 @@ IRNode *GenIR::localAlloc(IRNode *Arg, bool ZeroInit) {
|
|||
|
||||
// Zero the allocated region if so requested.
|
||||
if (ZeroInit) {
|
||||
Value *ZeroByte = ConstantInt::get(Context, APInt(8, 0, true));
|
||||
const bool MayThrow = false;
|
||||
Type *VoidTy = Type::getVoidTy(Context);
|
||||
callHelperImpl(CORINFO_HELP_MEMSET, VoidTy, (IRNode *)LocAlloc,
|
||||
Value *ZeroByte = ConstantInt::get(Context, APInt(8, 0, true));
|
||||
callHelperImpl(CORINFO_HELP_MEMSET, MayThrow, VoidTy, (IRNode *)LocAlloc,
|
||||
(IRNode *)ZeroByte, Arg);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче