*/
unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr);
-
void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute);
void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index,
LLVMAttribute);
void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
unsigned Align);
+void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
+ LLVMAttributeRef A);
+LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C,
+ LLVMAttributeIndex Idx,
+ unsigned KindID);
+void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
+ unsigned KindID);
+
/**
* Obtain the pointer to the function invoked by this instruction.
*
CALLSITE_DELEGATE_SETTER(addAttribute(i, Kind, Value));
}
+ void addAttribute(unsigned i, Attribute Attr) {
+ CALLSITE_DELEGATE_SETTER(addAttribute(i, Attr));
+ }
+
void removeAttribute(unsigned i, Attribute::AttrKind Kind) {
CALLSITE_DELEGATE_SETTER(removeAttribute(i, Kind));
}
CALLSITE_DELEGATE_GETTER(paramHasAttr(i, Kind));
}
+ Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
+ CALLSITE_DELEGATE_GETTER(getAttribute(i, Kind));
+ }
+
/// \brief Return true if the data operand at index \p i directly or
/// indirectly has the attribute \p A.
///
/// addAttribute - adds the attribute to the list of attributes.
void addAttribute(unsigned i, StringRef Kind, StringRef Value);
+ /// addAttribute - adds the attribute to the list of attributes.
+ void addAttribute(unsigned i, Attribute Attr);
+
/// removeAttribute - removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute::AttrKind Kind);
/// \brief Determine whether the call or the callee has the given attributes.
bool paramHasAttr(unsigned i, Attribute::AttrKind Kind) const;
+ /// \brief Get the attribute of a given kind at a position.
+ Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const;
+
/// \brief Return true if the data operand at index \p i has the attribute \p
/// A.
///
/// addAttribute - adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attribute::AttrKind Kind);
+ /// addAttribute - adds the attribute to the list of attributes.
+ void addAttribute(unsigned i, Attribute Attr);
+
/// removeAttribute - removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute::AttrKind Kind);
/// \brief Determine whether the call or the callee has the given attributes.
bool paramHasAttr(unsigned i, Attribute::AttrKind Kind) const;
+ /// \brief Get the attribute of a given kind at a position.
+ Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const;
+
/// \brief Return true if the data operand at index \p i has the attribute \p
/// A.
///
index, B)));
}
+void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
+ LLVMAttributeRef A) {
+ CallSite(unwrap<Instruction>(C)).addAttribute(Idx, unwrap(A));
+}
+
+LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C,
+ LLVMAttributeIndex Idx,
+ unsigned KindID) {
+ return wrap(CallSite(unwrap<Instruction>(C))
+ .getAttribute(Idx, (Attribute::AttrKind)KindID));
+}
+
+void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
+ unsigned KindID) {
+ CallSite(unwrap<Instruction>(C))
+ .removeAttribute(Idx, (Attribute::AttrKind)KindID);
+}
+
LLVMValueRef LLVMGetCalledValue(LLVMValueRef Instr) {
return wrap(CallSite(unwrap<Instruction>(Instr)).getCalledValue());
}
setAttributes(PAL);
}
+void CallInst::addAttribute(unsigned i, Attribute Attr) {
+ AttributeSet PAL = getAttributes();
+ PAL = PAL.addAttribute(getContext(), i, Attr);
+ setAttributes(PAL);
+}
+
void CallInst::removeAttribute(unsigned i, Attribute::AttrKind Kind) {
AttributeSet PAL = getAttributes();
PAL = PAL.removeAttribute(getContext(), i, Kind);
return false;
}
+Attribute CallInst::getAttribute(unsigned i, Attribute::AttrKind Kind) const {
+ return getAttributes().getAttribute(i, Kind);
+}
+
bool CallInst::dataOperandHasImpliedAttr(unsigned i,
Attribute::AttrKind Kind) const {
// There are getNumOperands() - 1 data operands. The last operand is the
setAttributes(PAL);
}
+void InvokeInst::addAttribute(unsigned i, Attribute Attr) {
+ AttributeSet PAL = getAttributes();
+ PAL = PAL.addAttribute(getContext(), i, Attr);
+ setAttributes(PAL);
+}
+
void InvokeInst::removeAttribute(unsigned i, Attribute::AttrKind Kind) {
AttributeSet PAL = getAttributes();
PAL = PAL.removeAttribute(getContext(), i, Kind);
setAttributes(PAL);
}
+Attribute InvokeInst::getAttribute(unsigned i,
+ Attribute::AttrKind Kind) const {
+ return getAttributes().getAttribute(i, Kind);
+}
+
void InvokeInst::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
AttributeSet PAL = getAttributes();
PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes);
define i32 @_D8test01494mainFMZi() personality i32 (i32, i32, i64, i8*, i8*)* @__sd_eh_personality {
body:
- %0 = invoke i8* @_d_allocmemory(i64 8)
+ %0 = invoke noalias i8* @_d_allocmemory(i64 8)
to label %then unwind label %landingPad
then: ; preds = %body
then1: ; preds = %then
%3 = bitcast i8* %0 to %C6object9Throwable*
- invoke void @__sd_eh_throw(%C6object9Throwable* %3)
+ invoke void @__sd_eh_throw(%C6object9Throwable* nonnull %3)
to label %then2 unwind label %landingPad
then2: ; preds = %then1
catch %C6object9ClassInfo* @C6object9Exception__ClassInfo
catch %C6object9ClassInfo* @C6object9Throwable__ClassInfo
%5 = extractvalue { i8*, i32 } %4, 1
- %6 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%C6object9ClassInfo* @C6object5Error__ClassInfo to i8*))
+ %6 = tail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object5Error__ClassInfo to i8*))
%7 = icmp eq i32 %6, %5
br i1 %7, label %catch, label %unwind3
ret i32 %merge
unwind3: ; preds = %landingPad
- %8 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%C6object9ClassInfo* @C6object9Exception__ClassInfo to i8*))
+ %8 = tail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Exception__ClassInfo to i8*))
%9 = icmp eq i32 %8, %5
br i1 %9, label %catch, label %unwind5
unwind5: ; preds = %unwind3
- %10 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%C6object9ClassInfo* @C6object9Throwable__ClassInfo to i8*))
+ %10 = tail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Throwable__ClassInfo to i8*))
%11 = icmp eq i32 %10, %5
br i1 %11, label %catch, label %unwind7
return Dst;
}
+ void CloneAttrs(LLVMValueRef Src, LLVMValueRef Dst) {
+ auto Ctx = LLVMGetModuleContext(M);
+ int ArgCount = LLVMGetNumArgOperands(Src);
+ for (int i = LLVMAttributeReturnIndex; i <= ArgCount; i++) {
+ for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) {
+ if (auto SrcA = LLVMGetCallSiteEnumAttribute(Src, i, k)) {
+ auto Val = LLVMGetEnumAttributeValue(SrcA);
+ auto A = LLVMCreateEnumAttribute(Ctx, k, Val);
+ LLVMAddCallSiteAttribute(Dst, i, A);
+ }
+ }
+ }
+ }
+
LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
check_value_kind(Src, LLVMInstructionValueKind);
if (!LLVMIsAInstruction(Src))
LLVMBasicBlockRef Unwind = DeclareBB(LLVMGetUnwindDest(Src));
Dst = LLVMBuildInvoke(Builder, Fn, Args.data(), ArgCount,
Then, Unwind, Name);
+ CloneAttrs(Src, Dst);
break;
}
case LLVMUnreachable:
LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
LLVMSetTailCall(Dst, LLVMIsTailCall(Src));
+ CloneAttrs(Src, Dst);
break;
}
case LLVMResume: {