From 4e14c8337b5a0392193227659f004aeeb7fabd23 Mon Sep 17 00:00:00 2001 From: Amaury Sechet Date: Wed, 15 Jun 2016 05:14:29 +0000 Subject: [PATCH] Add support for callsite in the new C API for attributes Summary: The second consumer of attributes. Reviewers: Wallbraker, whitequark, echristo, rafael, jyknight Subscribers: mehdi_amini Differential Revision: http://reviews.llvm.org/D21266 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272754 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm-c/Core.h | 9 ++++++++- include/llvm/IR/CallSite.h | 8 ++++++++ include/llvm/IR/Instructions.h | 12 ++++++++++++ lib/IR/Core.cpp | 18 ++++++++++++++++++ lib/IR/Instructions.cpp | 21 +++++++++++++++++++++ test/Bindings/llvm-c/invoke.ll | 10 +++++----- tools/llvm-c-test/echo.cpp | 16 ++++++++++++++++ 7 files changed, 88 insertions(+), 6 deletions(-) diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 3d1ebc531c8..6257e758b1e 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -2587,13 +2587,20 @@ void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC); */ 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. * diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index be93636d4c8..b423ecc6631 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -313,6 +313,10 @@ public: 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)); } @@ -336,6 +340,10 @@ public: 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. /// diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 5b5c1ed59eb..37f64750cd6 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1623,6 +1623,9 @@ public: /// 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); @@ -1651,6 +1654,9 @@ public: /// \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. /// @@ -3564,6 +3570,9 @@ public: /// 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); @@ -3592,6 +3601,9 @@ public: /// \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. /// diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index 6f0217e3d1e..c965063d8c7 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -2201,6 +2201,24 @@ void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, index, B))); } +void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, + LLVMAttributeRef A) { + CallSite(unwrap(C)).addAttribute(Idx, unwrap(A)); +} + +LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C, + LLVMAttributeIndex Idx, + unsigned KindID) { + return wrap(CallSite(unwrap(C)) + .getAttribute(Idx, (Attribute::AttrKind)KindID)); +} + +void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, + unsigned KindID) { + CallSite(unwrap(C)) + .removeAttribute(Idx, (Attribute::AttrKind)KindID); +} + LLVMValueRef LLVMGetCalledValue(LLVMValueRef Instr) { return wrap(CallSite(unwrap(Instr)).getCalledValue()); } diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp index 01d180e4abe..98d37074b4a 100644 --- a/lib/IR/Instructions.cpp +++ b/lib/IR/Instructions.cpp @@ -343,6 +343,12 @@ void CallInst::addAttribute(unsigned i, StringRef Kind, StringRef Value) { 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); @@ -380,6 +386,10 @@ bool CallInst::paramHasAttr(unsigned i, Attribute::AttrKind Kind) const { 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 @@ -702,6 +712,12 @@ void InvokeInst::addAttribute(unsigned i, Attribute::AttrKind Kind) { 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); @@ -716,6 +732,11 @@ void InvokeInst::removeAttribute(unsigned i, Attribute Attr) { 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); diff --git a/test/Bindings/llvm-c/invoke.ll b/test/Bindings/llvm-c/invoke.ll index 0cd70a74e48..613a18de1a8 100644 --- a/test/Bindings/llvm-c/invoke.ll +++ b/test/Bindings/llvm-c/invoke.ll @@ -21,7 +21,7 @@ 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 @@ -33,7 +33,7 @@ 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 @@ -46,7 +46,7 @@ landingPad: ; preds = %then1, %then, %body 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 @@ -55,12 +55,12 @@ catch: ; preds = %unwind5, %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 diff --git a/tools/llvm-c-test/echo.cpp b/tools/llvm-c-test/echo.cpp index 73444b46d93..72ff138c74e 100644 --- a/tools/llvm-c-test/echo.cpp +++ b/tools/llvm-c-test/echo.cpp @@ -375,6 +375,20 @@ struct FunCloner { 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)) @@ -439,6 +453,7 @@ struct FunCloner { LLVMBasicBlockRef Unwind = DeclareBB(LLVMGetUnwindDest(Src)); Dst = LLVMBuildInvoke(Builder, Fn, Args.data(), ArgCount, Then, Unwind, Name); + CloneAttrs(Src, Dst); break; } case LLVMUnreachable: @@ -599,6 +614,7 @@ struct FunCloner { LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src)); Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name); LLVMSetTailCall(Dst, LLVMIsTailCall(Src)); + CloneAttrs(Src, Dst); break; } case LLVMResume: { -- 2.50.1