diff options
Diffstat (limited to 'lib/IR/Core.cpp')
-rw-r--r-- | lib/IR/Core.cpp | 156 |
1 files changed, 123 insertions, 33 deletions
diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index 3576137..f007616 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -26,8 +26,8 @@ #include "llvm/IR/InlineAsm.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" -#include "llvm/PassManager.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" @@ -556,12 +556,31 @@ int LLVMHasMetadata(LLVMValueRef Inst) { } LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) { - return wrap(unwrap<Instruction>(Inst)->getMetadata(KindID)); + auto *I = unwrap<Instruction>(Inst); + assert(I && "Expected instruction"); + if (auto *MD = I->getMetadata(KindID)) + return wrap(MetadataAsValue::get(I->getContext(), MD)); + return nullptr; +} + +// MetadataAsValue uses a canonical format which strips the actual MDNode for +// MDNode with just a single constant value, storing just a ConstantAsMetadata +// This undoes this canonicalization, reconstructing the MDNode. +static MDNode *extractMDNode(MetadataAsValue *MAV) { + Metadata *MD = MAV->getMetadata(); + assert((isa<MDNode>(MD) || isa<ConstantAsMetadata>(MD)) && + "Expected a metadata node or a canonicalized constant"); + + if (MDNode *N = dyn_cast<MDNode>(MD)) + return N; + + return MDNode::get(MAV->getContext(), MD); } -void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) { - unwrap<Instruction>(Inst) - ->setMetadata(KindID, MD ? unwrap<MDNode>(MD) : nullptr); +void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) { + MDNode *N = Val ? extractMDNode(unwrap<MetadataAsValue>(Val)) : nullptr; + + unwrap<Instruction>(Inst)->setMetadata(KindID, N); } /*--.. Conversion functions ................................................--*/ @@ -573,6 +592,21 @@ void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) { LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DEFINE_VALUE_CAST) +LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val) { + if (auto *MD = dyn_cast_or_null<MetadataAsValue>(unwrap(Val))) + if (isa<MDNode>(MD->getMetadata()) || + isa<ValueAsMetadata>(MD->getMetadata())) + return Val; + return nullptr; +} + +LLVMValueRef LLVMIsAMDString(LLVMValueRef Val) { + if (auto *MD = dyn_cast_or_null<MetadataAsValue>(unwrap(Val))) + if (isa<MDString>(MD->getMetadata())) + return Val; + return nullptr; +} + /*--.. Operations on Uses ..................................................--*/ LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val) { Value *V = unwrap(Val); @@ -598,10 +632,28 @@ LLVMValueRef LLVMGetUsedValue(LLVMUseRef U) { } /*--.. Operations on Users .................................................--*/ + +static LLVMValueRef getMDNodeOperandImpl(LLVMContext &Context, const MDNode *N, + unsigned Index) { + Metadata *Op = N->getOperand(Index); + if (!Op) + return nullptr; + if (auto *C = dyn_cast<ConstantAsMetadata>(Op)) + return wrap(C->getValue()); + return wrap(MetadataAsValue::get(Context, Op)); +} + LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index) { Value *V = unwrap(Val); - if (MDNode *MD = dyn_cast<MDNode>(V)) - return wrap(MD->getOperand(Index)); + if (auto *MD = dyn_cast<MetadataAsValue>(V)) { + if (auto *L = dyn_cast<ValueAsMetadata>(MD->getMetadata())) { + assert(Index == 0 && "Function-local metadata can only have one operand"); + return wrap(L->getValue()); + } + return getMDNodeOperandImpl(V->getContext(), + cast<MDNode>(MD->getMetadata()), Index); + } + return wrap(cast<User>(V)->getOperand(Index)); } @@ -616,8 +668,9 @@ void LLVMSetOperand(LLVMValueRef Val, unsigned Index, LLVMValueRef Op) { int LLVMGetNumOperands(LLVMValueRef Val) { Value *V = unwrap(Val); - if (MDNode *MD = dyn_cast<MDNode>(V)) - return MD->getNumOperands(); + if (isa<MetadataAsValue>(V)) + return LLVMGetMDNodeNumOperands(Val); + return cast<User>(V)->getNumOperands(); } @@ -658,7 +711,9 @@ LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty) { LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str, unsigned SLen) { - return wrap(MDString::get(*unwrap(C), StringRef(Str, SLen))); + LLVMContext &Context = *unwrap(C); + return wrap(MetadataAsValue::get( + Context, MDString::get(Context, StringRef(Str, SLen)))); } LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) { @@ -667,8 +722,29 @@ LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) { LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals, unsigned Count) { - return wrap(MDNode::get(*unwrap(C), - makeArrayRef(unwrap<Value>(Vals, Count), Count))); + LLVMContext &Context = *unwrap(C); + SmallVector<Metadata *, 8> MDs; + for (auto *OV : makeArrayRef(Vals, Count)) { + Value *V = unwrap(OV); + Metadata *MD; + if (!V) + MD = nullptr; + else if (auto *C = dyn_cast<Constant>(V)) + MD = ConstantAsMetadata::get(C); + else if (auto *MDV = dyn_cast<MetadataAsValue>(V)) { + MD = MDV->getMetadata(); + assert(!isa<LocalAsMetadata>(MD) && "Unexpected function-local metadata " + "outside of direct argument to call"); + } else { + // This is function-local metadata. Pretend to make an MDNode. + assert(Count == 1 && + "Expected only one operand to function-local metadata"); + return wrap(MetadataAsValue::get(Context, LocalAsMetadata::get(V))); + } + + MDs.push_back(MD); + } + return wrap(MetadataAsValue::get(Context, MDNode::get(Context, MDs))); } LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) { @@ -676,25 +752,35 @@ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) { } const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len) { - if (const MDString *S = dyn_cast<MDString>(unwrap(V))) { - *Len = S->getString().size(); - return S->getString().data(); - } + if (const auto *MD = dyn_cast<MetadataAsValue>(unwrap(V))) + if (const MDString *S = dyn_cast<MDString>(MD->getMetadata())) { + *Len = S->getString().size(); + return S->getString().data(); + } *Len = 0; return nullptr; } unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V) { - return cast<MDNode>(unwrap(V))->getNumOperands(); + auto *MD = cast<MetadataAsValue>(unwrap(V)); + if (isa<ValueAsMetadata>(MD->getMetadata())) + return 1; + return cast<MDNode>(MD->getMetadata())->getNumOperands(); } void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest) { - const MDNode *N = cast<MDNode>(unwrap(V)); + auto *MD = cast<MetadataAsValue>(unwrap(V)); + if (auto *MDV = dyn_cast<ValueAsMetadata>(MD->getMetadata())) { + *Dest = wrap(MDV->getValue()); + return; + } + const auto *N = cast<MDNode>(MD->getMetadata()); const unsigned numOperands = N->getNumOperands(); + LLVMContext &Context = unwrap(V)->getContext(); for (unsigned i = 0; i < numOperands; i++) - Dest[i] = wrap(N->getOperand(i)); + Dest[i] = getMDNodeOperandImpl(Context, N, i); } unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name) @@ -710,8 +796,9 @@ void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRe NamedMDNode *N = unwrap(M)->getNamedMetadata(name); if (!N) return; + LLVMContext &Context = unwrap(M)->getContext(); for (unsigned i=0;i<N->getNumOperands();i++) - Dest[i] = wrap(N->getOperand(i)); + Dest[i] = wrap(MetadataAsValue::get(Context, N->getOperand(i))); } void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name, @@ -720,9 +807,9 @@ void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name, NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(name); if (!N) return; - MDNode *Op = Val ? unwrap<MDNode>(Val) : nullptr; - if (Op) - N->addOperand(Op); + if (!Val) + return; + N->addOperand(extractMDNode(unwrap<MetadataAsValue>(Val))); } /*--.. Operations on scalar constants ......................................--*/ @@ -1543,7 +1630,7 @@ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, auto *PTy = cast<PointerType>(unwrap(Ty)); return wrap(GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), GlobalValue::ExternalLinkage, Name, - unwrap<GlobalObject>(Aliasee), unwrap(M))); + unwrap<Constant>(Aliasee), unwrap(M))); } /*--.. Operations on functions .............................................--*/ @@ -2092,13 +2179,16 @@ void LLVMDisposeBuilder(LLVMBuilderRef Builder) { /*--.. Metadata builders ...................................................--*/ void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) { - MDNode *Loc = L ? unwrap<MDNode>(L) : nullptr; + MDNode *Loc = + L ? cast<MDNode>(unwrap<MetadataAsValue>(L)->getMetadata()) : nullptr; unwrap(Builder)->SetCurrentDebugLocation(DebugLoc::getFromDILocation(Loc)); } LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) { - return wrap(unwrap(Builder)->getCurrentDebugLocation() - .getAsMDNode(unwrap(Builder)->getContext())); + LLVMContext &Context = unwrap(Builder)->getContext(); + return wrap(MetadataAsValue::get( + Context, + unwrap(Builder)->getCurrentDebugLocation().getAsMDNode(Context))); } void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst) { @@ -2755,11 +2845,11 @@ LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void) { /*===-- Pass Manager ------------------------------------------------------===*/ LLVMPassManagerRef LLVMCreatePassManager() { - return wrap(new PassManager()); + return wrap(new legacy::PassManager()); } LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M) { - return wrap(new FunctionPassManager(unwrap(M))); + return wrap(new legacy::FunctionPassManager(unwrap(M))); } LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef P) { @@ -2768,19 +2858,19 @@ LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef P) { } LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) { - return unwrap<PassManager>(PM)->run(*unwrap(M)); + return unwrap<legacy::PassManager>(PM)->run(*unwrap(M)); } LLVMBool LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM) { - return unwrap<FunctionPassManager>(FPM)->doInitialization(); + return unwrap<legacy::FunctionPassManager>(FPM)->doInitialization(); } LLVMBool LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F) { - return unwrap<FunctionPassManager>(FPM)->run(*unwrap<Function>(F)); + return unwrap<legacy::FunctionPassManager>(FPM)->run(*unwrap<Function>(F)); } LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM) { - return unwrap<FunctionPassManager>(FPM)->doFinalization(); + return unwrap<legacy::FunctionPassManager>(FPM)->doFinalization(); } void LLVMDisposePassManager(LLVMPassManagerRef PM) { |